PIPS
transformer.h File Reference

Go to the source code of this file.

Macros

#define SEMANTICS_MODULE_NAME   "*SEMANTICS*"
 Warning! Do not modify this file that is automatically generated! More...
 
#define SEMANTICS_SEPARATOR   '#'
 Must be used in suffixes and prefixes below. More...
 
#define OLD_VALUE_PREFIX   "o#"
 internal entity names (FI: I should have used suffixes to be consistent with external suffixes More...
 
#define INTERMEDIATE_VALUE_PREFIX   "i#"
 
#define TEMPORARY_VALUE_PREFIX   "t#"
 
#define NEW_VALUE_SUFFIX   "#new"
 external suffixes (NEW_VALUE_SUFFIX is not used, new values are represented by the variable itself, i.e. More...
 
#define OLD_VALUE_SUFFIX   "#init"
 
#define INTERMEDIATE_VALUE_SUFFIX   "#int"
 
#define ADDRESS_OF_SUFFIX   "#addressof"
 
#define SIZEOF_SUFFIX   "#sizeof"
 

Functions

transformer transformer_dup (transformer)
 cproto-generated files More...
 
void transformer_free (transformer)
 
void free_transformers (transformer,...)
 
void old_transformer_free (transformer)
 
transformer transformer_identity (void)
 Allocate an identity transformer. More...
 
transformer transformer_empty (void)
 Allocate an empty transformer. More...
 
transformer empty_transformer (transformer)
 Do not allocate an empty transformer, but transform an allocated transformer into an empty_transformer. More...
 
bool transformer_identity_p (transformer)
 Check that t is an identity function. More...
 
bool transformer_is_empty_p (transformer)
 Check that transformer t is the canonical representation of an empty transformer. More...
 
bool transformer_is_rn_p (transformer)
 Check that transformer t is the canonical representation of the whole afine space defined by its basis. More...
 
transformer transformer_add_sign_information (transformer, entity, int)
 CHANGE THIS NAME: no loop index please, it's not directly linked to loops!!! More...
 
transformer transformer_add_variable_incrementation (transformer, entity, Pvecteur)
 transformer transformer_add_loop_index(transformer t, entity i, Pvecteur incr): add the index incrementation expression incr for loop index i to transformer t. More...
 
transformer transformer_add_variable_update (transformer, entity)
 Add an update of variable v into t. More...
 
transformer transformer_add_value_update (transformer, entity)
 Add an update of variable v to t (a value cannot be updated) More...
 
transformer transformer_add_variables_update (transformer, list)
 
transformer transformer_constraint_add (transformer, Pvecteur, bool)
 
transformer transformer_inequality_add (transformer, Pvecteur)
 
transformer transformer_equality_add (transformer, Pvecteur)
 
transformer transformer_equalities_add (transformer, Pcontrainte)
 
transformer transformer_inequalities_add (transformer, Pcontrainte)
 Warning: More...
 
transformer transformer_add_identity (transformer, entity)
 
transformer transformer_add_equality (transformer, entity, entity)
 Add an equality between two values (two variables?) More...
 
transformer transformer_add_equality_with_integer_constant (transformer, entity, long long int)
 Add an equality between a value and an integer constant: v==cst. More...
 
transformer transformer_add_inequality (transformer, entity, entity, bool)
 Add the equality v1 <= v2 or v1 < v2. More...
 
transformer transformer_add_inequality_with_integer_constraint (transformer, entity, long long int, bool)
 Add the inequality v <= cst or v >= cst. More...
 
transformer transformer_add_inequality_with_affine_term (transformer, entity, entity, int, int, bool)
 Add the inequality v <= a x + cst or v >= a x + cst. More...
 
transformer transformer_add_equality_with_affine_term (transformer, entity, entity, int, int)
 Add the equality v = a x + cst. More...
 
transformer transformer_add_inequality_with_linear_term (transformer, entity, entity, int, bool)
 Add the inequality v <= a x or v >= a x. More...
 
transformer transformer_add_3d_affine_constraint (transformer, int, entity, int, entity, int, entity, int, bool)
 Add the constraint a1 v1 + a2 v2 + a3 v3 + cst <= or == 0. More...
 
bool transformer_argument_consistency_p (transformer)
 
bool transformer_argument_weak_consistency_p (transformer)
 
bool transformer_argument_general_consistency_p (transformer, bool)
 
bool transformer_consistency_p (transformer)
 FI: I do not know if this procedure should always return or fail when an inconsistency is found. More...
 
bool transformers_consistency_p (list)
 
bool transformer_weak_consistency_p (transformer)
 Interprocedural transformers do not meet all conditions. More...
 
bool transformer_general_consistency_p (transformer, bool)
 
bool transformer_internal_consistency_p (transformer)
 Same as above but equivalenced variables should not appear in the argument list or in the predicate basis. More...
 
list transformer_projectable_values (transformer)
 
bool value_belongs_to_transformer_space (entity, transformer)
 
void add_value_to_transformer_space (entity, transformer)
 
transformer precondition_to_abstract_store (transformer)
 Get rid of all old values and arguments. More...
 
transformer transformer_add_modified_variable (transformer, entity)
 FI: this function does not end up with a consistent transformer because the old value is not added to the basis of sc. More...
 
transformer transformer_add_modified_variable_entity (transformer, entity)
 FI: like the previous function, but supposed to end up with a consistent transformer. More...
 
transformer move_transformer (transformer, transformer)
 Move arguments and predicate of t2 into t1, free old arguments and predicate of t1, free what's left of t2. More...
 
bool transformer_equations_constrain_variable_p (const transformer, const entity)
 Is value v used with a non-zero coefficient by the equations of transformer t? More...
 
bool transformer_inequalities_constrain_variable_p (const transformer, const entity)
 Is value v used with a non-zero coefficient by the inequalities of transformer t? More...
 
transformer transformer_convex_hull (transformer, transformer)
 convex_hull.c More...
 
transformer transformer_halbwachs_fix_point (transformer)
 
transformer transformer_equality_fix_point (transformer)
 Let A be the affine loop transfert function. More...
 
void build_transfer_equations (Pcontrainte, Pcontrainte *, Pbase *)
 
bool transfer_equation_p (Pvecteur)
 A transfer equation is an explicit equation giving one new value as a function of old values and a constant term. More...
 
entity new_value_in_transfer_equation (Pvecteur)
 
bool sub_basis_p (Pbase, Pbase)
 FI: should be moved in base.c. More...
 
void equations_to_bases (Pcontrainte, Pbase *, Pbase *)
 
transformer transformer_pattern_fix_point (transformer)
 This fixpoint function was developped to present a talk at FORMA. More...
 
Pvecteur look_for_the_best_counter (Pcontrainte)
 Try to identify a loop counter among the equation egs. More...
 
Psysteme sc_eliminate_constant_terms (Psysteme, Pvecteur)
 Eliminate all constant terms in sc using v. More...
 
Pcontrainte constraints_eliminate_constant_terms (Pcontrainte, Pvecteur)
 
Psysteme sc_keep_invariants_only (Psysteme)
 This function cannot be moved into the Linear library. More...
 
Pcontrainte constraints_keep_invariants_only (Pcontrainte)
 
bool invariant_vector_p (Pvecteur)
 A vector (in fact, a constraint) represents an invariant if it is a sum of delta for each variable. More...
 
Psysteme sc_multiply_constant_terms (Psysteme, Variable, bool)
 Specific for the derivative fix point: each constant term in the constraints is multiplied by ik which is not in sc's basis, and ik is added to the basis is necessary. More...
 
transformer transformer_derivative_fix_point (transformer)
 Computation of a transitive closure using constraints on the discrete derivative. More...
 
list transformers_derivative_fix_point (list)
 
transformer transformer_basic_fix_point (transformer)
 Computation of a fix point: drop all constraints, remember which variables are changed. More...
 
transformer any_transformer_to_k_closure (transformer, transformer, transformer, transformer, transformer, int, bool)
 Derived from any_loop_to_k_transformer() More...
 
transformer print_transformer (transformer)
 io.c More...
 
transformer print_any_transformer (transformer)
 For debugging without problem from temporary values. More...
 
list print_transformers (list)
 
transformer fprint_transformer (FILE *, transformer, get_variable_name_t)
 
list fprint_transformers (FILE *, list, get_variable_name_t)
 
char * dump_value_name (entity)
 char * dump_value_name(e): used as functional argument because entity_name is a macro More...
 
void dump_transformer (transformer)
 
transformer simple_equality_to_transformer (entity, entity, bool)
 transformer.c More...
 
transformer simple_unary_minus_to_transformer (entity, entity)
 
transformer generic_equality_to_transformer (entity, entity, bool, bool)
 
transformer simple_addition_to_transformer (entity, entity, entity, bool)
 e and e1 and e2 are assumed to be values. More...
 
transformer relation_to_transformer (entity, entity, entity, bool)
 e and f are assumed to be values. More...
 
transformer transformer_combine (volatile transformer, transformer)
 transformer transformer_combine(transformer t1, transformer t2): compute the composition of transformers t1 and t2 (t1 then t2) More...
 
list transformers_combine (list, transformer)
 Combine each transformer of transformer list tl1 with t2. More...
 
list one_to_one_transformers_combine (list, list)
 Combine each transformer of transformer list tl1 with the corresponding transformer in transformer list tl2. More...
 
transformer transformer_safe_combine_with_warnings (transformer, transformer)
 Transformer tf1 and tf2 are supposed to be independent but they may interfere, for instance because subexpressions have non-standard conformant side effects. More...
 
transformer transformer_intersection (transformer, transformer)
 tf is a new transformer that receives the constraints in t1 and t2. More...
 
transformer transformer_image_intersection (transformer, transformer)
 allocate a new transformer based on transformer t1 and postcondition t2 More...
 
transformer transformer_safe_intersection (transformer, transformer)
 Allocate a new transformer. More...
 
transformer transformer_safe_image_intersection (transformer, transformer)
 Allocate a new transformer. More...
 
transformer transformer_domain_intersection (transformer, transformer)
 Restrict the domain of the relation tf with pre. More...
 
transformer transformer_safe_domain_intersection (transformer, transformer)
 If tf and pre are defined, update tf. More...
 
transformer transformer_range (transformer)
 Return the range of relation tf in a newly allocated transformer. More...
 
transformer transformer_safe_range (transformer)
 
list transformers_range (list)
 Substitute each transformer in list tfl by its range. More...
 
transformer transformer_to_domain (transformer)
 Return the domain of relation tf in a newly allocated transformer. More...
 
transformer transformer_safe_domain (transformer)
 
transformer transformer_range_intersection (transformer, transformer)
 Allocate a new transformer rtf that is tf with its range restricted by the range r. More...
 
transformer transformer_intersect_range_with_domain (transformer)
 When tf is used repeatedly in a loop, the range is part of the domain from iteration 2 to the end. More...
 
transformer transformer_normalize (transformer, int)
 Eliminate (some) rational or integer redundancy. More...
 
transformer transformer_safe_normalize (transformer, int)
 
list transformers_safe_normalize (list, int)
 
bool transformer_with_temporary_values_p (transformer)
 Does transformer tf use temporary values? More...
 
transformer transformer_temporary_value_projection (transformer)
 
transformer safe_transformer_projection (transformer, list)
 t may be undefined, args may contain values unrelated to t More...
 
transformer transformer_return_value_projection (entity, transformer)
 Project return values that are not linked to function f. More...
 
transformer transformer_projection (transformer, list)
 values in args must be in t's base More...
 
transformer transformer_arguments_projection (transformer)
 transformer transformer_projection(transformer t); projection of t along the hyperplane defined by values of variables in arguments; this generate a projection and not a cylinder based on the projection More...
 
Psysteme no_elim (Psysteme)
 
transformer transformer_projection_with_redundancy_elimination (transformer, list, Psysteme(*)(Psysteme))
 It is not clear if this function projects values or variables. More...
 
transformer transformer_projection_without_check (transformer, list, Psysteme(*)(Psysteme))
 In some cases, you know the projection will result in a non-consistent transformer that will be fixed later. More...
 
transformer transformer_projection_with_redundancy_elimination_and_check (volatile transformer, list, Psysteme(*)(Psysteme), bool)
 
transformer transformer_apply (transformer, transformer)
 transformer transformer_apply(transformer tf, transformer pre): apply transformer tf on precondition pre to obtain postcondition post More...
 
list transformer_apply_generic (list, transformer, bool)
 Generates a new list of postconditions, one for each transformer in tl, unless the postcondition is empty and keep_p is FALSE. More...
 
list transformer_apply_map (list, transformer)
 Generates a new list of postconditions, one for each transformer in tl, unless the postcondition is empty. More...
 
list transformers_apply (list, transformer)
 Same as previous one, but with a more normalized name. More...
 
list transformers_apply_and_keep_all (list, transformer)
 Same as previous one, but with a more normalized name. More...
 
transformer transformer_safe_apply (transformer, transformer)
 
list transformers_safe_apply (list, transformer)
 returns a list of postconditions, one for each transformer in tl More...
 
transformer transformer_inverse_apply (transformer, transformer)
 transformer transformer_inverse_apply(transformer tf, transformer post): apply transformer tf on precondition pre to obtain postcondition post More...
 
transformer transformer_safe_inverse_apply (transformer, transformer)
 
transformer transformer_filter (transformer, list)
 transformer transformer_filter(transformer t, cons * args): projection of t along the hyperplane defined by entities in args; this generate a projection and not a cylinder based on the projection; More...
 
transformer transformer_variables_filter (transformer, list)
 Transformers are dealing with variables and/or variable values. More...
 
bool transformer_affect_linear_p (transformer, Pvecteur)
 bool transformer_affect_linear_p(transformer tf, Pvecteur l): returns TRUE if there is a state s such that eval(l, s) != eval(l, tf(s)); returns false if l is invariant w.r.t. More...
 
bool transformer_affect_transformer_p (transformer, transformer)
 Transformer tf1 affects transformer tf2 if values modified by tf1 appear in any constraint of tf2. More...
 
bool transformer_safe_affect_transformer_p (transformer, transformer)
 
transformer args_to_transformer (list)
 Generates a transformer abstracting a totally unknown modification of the values associated to variables in list le. More...
 
transformer invariant_wrt_transformer (transformer, transformer)
 transformer invariant_wrt_transformer(transformer p, transformer tf): Assume that tf is a fix-point operator. More...
 
transformer transformer_value_substitute (transformer, entity, entity)
 transformer transformer_value_substitute(transformer t, entity e1, entity e2): if e2 does not appear in t initially: replaces occurences of value e1 by value e2 in transformer t's arguments and relation fields; else error fi More...
 
bool transformer_value_substitutable_p (transformer, entity, entity)
 If e1 does not appear in t, it is substitutable. More...
 
transformer transformer_safe_value_substitute (transformer, entity, entity)
 
Pvecteur simplify_float_constraint (Pvecteur, bool)
 If v is a not a float constraint, retun v. More...
 
Psysteme simplify_float_constraint_system (Psysteme)
 Simplify float constraints and possibly detect. More...
 
bool transformer_empty_p (transformer)
 If true is returned, the transformer certainly is empty. More...
 
bool transformer_strongly_empty_p (transformer)
 If true is returned, the transformer certainly is empty. More...
 
bool transformer_to_1D_lattice (entity, transformer, Value *, Value *)
 See if the equations in transformer "pre" constraint variable "v" by v = gcd x + c, where x is a free variable. More...
 
transformer formal_and_actual_parameters_association (call, transformer)
 formal_and_actual_parameters_association(call c, transformer pre): Add equalities between actual and formal parameters binding by call c to pre pre := pre U {f = expr } i i for all i such that formal fi is an integer scalar variable and expression expr-i is affine More...
 
bool same_dimension_p (entity, entity, list, size_t, transformer)
 This function returns true if the actual array and the dummy array have the same dimension number i, with respect to the current context (precondition + association) In case if the actual argument is an array element, we have to add the following condition: the i-th subscript of the array element is equal to its correspond lower bound. More...
 
list transformer_to_potential_stub_translation (transformer, entity)
 
list transformer_to_analyzed_array_locations (transformer)
 
list transformer_to_analyzed_locations (transformer)
 The list of location entities that appear in the basis of the transformer predicate. More...
 
list transformer_to_analyzed_arrays (transformer)
 The list of array entities that appear in the basis of the transformer predicate as array element locations. More...
 
list transformer_to_local_values (transformer, list)
 Build a list of values appearing in tf that are linked to a variable in dl. More...
 
bool hash_entity_to_values_undefined_p (void)
 value.c More...
 
void reset_value_counters (void)
 
void reset_temporary_value_counter (void)
 
int number_of_temporary_values (void)
 
void set_analyzed_types (void)
 
void reset_analyzed_types (void)
 
bool integer_analyzed_p (void)
 
bool boolean_analyzed_p (void)
 
bool string_analyzed_p (void)
 
bool float_analyzed_p (void)
 
bool complex_analyzed_p (void)
 
bool pointer_analyzed_p (void)
 
bool constant_path_analyzed_p (void)
 
bool analyzed_basic_p (basic)
 The basic corresponds to one of the analyzed types. More...
 
bool analyzed_type_p (type)
 The type t is one of the analyzed types. More...
 
bool analyzed_struct_p (entity)
 Does struct s contain directly or indirectly a field that may be analyzable? More...
 
bool analyzed_struct_type_p (type)
 
bool analyzed_array_p (entity)
 Does array a contain directly or indirectly a field that may be analyzable? More...
 
bool analyzed_array_type_p (type)
 
bool analyzed_entity_p (entity)
 
bool analyzable_scalar_entity_p (entity)
 The entity type is one of the analyzed types. More...
 
bool analyzed_constant_p (entity)
 The constant may appear as a variable in the linear systems. More...
 
bool analyzed_reference_p (reference)
 FI: Nelson explains the motivation for can_be_constant_path_p() but I do not understand them. More...
 
entity make_local_temporary_value_entity (type)
 
entity make_local_temporary_value_entity_with_basic (basic)
 
entity make_local_temporary_integer_value_entity (void)
 
bool local_old_value_entity_p (entity)
 Return true if an entity is a local old value (such as "o#0" for a global value "i#init"...). More...
 
bool local_intermediate_value_entity_p (entity)
 
bool local_temporary_value_entity_p (entity)
 
bool global_new_value_p (entity)
 GLOBAL VALUES. More...
 
bool global_old_value_p (entity)
 Return true if an entity is a global old value (such as "i#init"...). More...
 
bool global_intermediate_value_p (entity)
 
entity global_new_value_to_global_old_value (entity)
 
const char * global_value_name_to_user_name (const char *)
 HASH TABLE USE. More...
 
const char * external_value_name (entity)
 
const char * pips_user_value_name (entity)
 This function is called many times when the constraints and the system of constraints are sorted using lexicographic information based on this particular value name. More...
 
entity entity_to_new_value (entity)
 
entity entity_to_old_value (entity)
 
entity entity_to_intermediate_value (entity)
 
entity reference_to_address_of_value (reference)
 
entity type_to_sizeof_value (type)
 
bool entity_has_values_p (entity)
 This function could be made more robust by checking the storage of e. More...
 
bool new_value_entity_p (entity)
 the following three functions are directly or indirectly relative to the current module and its value hash tables. More...
 
bool old_value_entity_p (entity)
 
bool intermediate_value_entity_p (entity)
 
bool address_of_value_entity_p (entity)
 
bool sizeof_value_entity_p (entity)
 
bool value_entity_p (entity)
 
void print_value_mappings (void)
 
list modified_variables_with_values (void)
 Return the list of all analyzed variables which are modified in the current module. More...
 
void test_mapping_entry_consistency (void)
 
int number_of_analyzed_values (void)
 
int aproximate_number_of_analyzed_variables (void)
 
int number_of_analyzed_variables (void)
 FI: looks more like the number of values used. More...
 
void allocate_value_mappings (int, int, int)
 
bool hash_value_to_name_undefined_p (void)
 
void error_reset_value_mappings (void)
 To be called by error handler only. More...
 
void free_value_mappings (void)
 Normal call to free the mappings. More...
 
void error_free_value_mappings (void)
 To be called by an error handler. More...
 
entity reference_to_address_entity (reference)
 The address is the address of a variable or of a reference such as &a[5], not a of a value. More...
 
void add_address_of_value (reference, type)
 
void add_sizeof_value (type)
 For a given architecture, sizeof(t) is a constant. More...
 
void add_new_value (entity)
 
void add_new_alias_value (entity, entity)
 
entity external_entity_to_new_value (entity)
 
entity external_entity_to_old_value (entity)
 
void add_old_value (entity)
 
void add_old_alias_value (entity, entity)
 
void add_intermediate_value (entity)
 
void add_intermediate_alias_value (entity, entity)
 
void add_local_old_value (entity)
 
void add_local_intermediate_value (entity)
 
void remove_entity_values (entity, bool)
 
void add_synonym_values (entity, entity, bool)
 
entity value_to_variable (entity)
 Get the primitive variable associated to any value involved in a transformer. More...
 
entity old_value_to_new_value (entity)
 
entity new_value_to_old_value (entity)
 
entity value_alias (entity)
 Static aliasing. More...
 
Pvecteur vect_variables_to_values (Pvecteur)
 FI: not used, not debugged. More...
 
string value_full_name (entity)
 for debugging purposes More...
 
const char * readable_value_name (entity)
 For debugging purposes, we might have to print system with temporary values. More...
 
string transformer_to_string (transformer)
 prettyprint.c More...
 
string precondition_to_string (transformer)
 
string arguments_to_string (string, list)
 
string relation_to_string (string, Psysteme, char *(*)(entity))
 
const char * generic_value_name (entity)
 
list merge_transformer_lists (list, list)
 transformer_list.c More...
 
bool check_transformer_list (list)
 What do we want to impose? More...
 
list combine_transformer_lists (list, list)
 each transformer of tl1 must be combined with a transformer of tl2, including the identity transformer. More...
 
list apply_transformer_lists_generic (list, list, bool)
 each transformer of tl1 must be applied to each precondition of tl2, including the identity transformer. More...
 
list apply_transformer_lists (list, list)
 
list apply_transformer_lists_with_exclusion (list, list)
 
list clean_up_transformer_list (list)
 Eliminate empty transformers and keep at most one identity transformer, placed as first list element. More...
 
list two_transformers_to_list (transformer, transformer)
 Transformer two transformers into a correct transformer list. More...
 
transformer generic_transformer_list_to_transformer (list, bool)
 Reduce the transformer list with the convex hull operator. More...
 
transformer transformer_list_to_transformer (list)
 Reduce the transformer list ltl to one transformer using the convex hull operator. More...
 
transformer active_transformer_list_to_transformer (list)
 Reduce the sublist of active transformers in the transformer list ltl to one transformer using the convex hull operator. More...
 
list transformer_list_to_active_transformer_list (list)
 
transformer transformer_list_closure_to_precondition (list, transformer, transformer)
 Relay to select a heuristic. More...
 
list transformer_list_safe_variables_projection (list, list)
 Returns a new list of newly allocated projected transformers. More...
 
list transformer_list_to_argument (list)
 Returns the list of variables modified by at least one transformer in tl. More...
 
list transformer_list_with_effect (list, entity)
 build a sublist sl of the transformer list tl with transformers that modify the value of variable v More...
 
list transformer_list_preserved_variables (list, list, list)
 returns the list of variables in vl which are not modified by transformers belonging to tl-tl_v. More...
 
transformer transformer_list_multiple_closure_to_precondition (list, transformer, transformer)
 When some variables are not modified by some transformers, use projections on subsets to increase the number of identity transformers and to increase the accuracy of the loop precondition. More...
 
Psysteme transformer_derivative_constraints (transformer)
 Allocate a new constraint system sc(dx) with dx=x'-x and t(x,x') More...
 
transformer transformer_list_generic_transitive_closure (list, bool)
 Computation of an upper approximation of a transitive closure using constraints on the discrete derivative for a list of transformers. More...
 
transformer transformer_list_transitive_closure (list)
 Compute (U tfl)*. More...
 
transformer transformer_list_transitive_closure_plus (list)
 Compute (U tfl)+. More...
 

Variables

transformer(* transformer_fix_point_operator )(transformer)
 fix_point.c More...
 

Macro Definition Documentation

◆ ADDRESS_OF_SUFFIX

#define ADDRESS_OF_SUFFIX   "#addressof"

Definition at line 56 of file transformer.h.

◆ INTERMEDIATE_VALUE_PREFIX

#define INTERMEDIATE_VALUE_PREFIX   "i#"

Definition at line 46 of file transformer.h.

◆ INTERMEDIATE_VALUE_SUFFIX

#define INTERMEDIATE_VALUE_SUFFIX   "#int"

Definition at line 54 of file transformer.h.

◆ NEW_VALUE_SUFFIX

#define NEW_VALUE_SUFFIX   "#new"

external suffixes (NEW_VALUE_SUFFIX is not used, new values are represented by the variable itself, i.e.

new value suffix is the empty string "")

Definition at line 52 of file transformer.h.

◆ OLD_VALUE_PREFIX

#define OLD_VALUE_PREFIX   "o#"

internal entity names (FI: I should have used suffixes to be consistent with external suffixes

Definition at line 45 of file transformer.h.

◆ OLD_VALUE_SUFFIX

#define OLD_VALUE_SUFFIX   "#init"

Definition at line 53 of file transformer.h.

◆ SEMANTICS_MODULE_NAME

#define SEMANTICS_MODULE_NAME   "*SEMANTICS*"

Warning! Do not modify this file that is automatically generated!

Modify src/Libs/transformer/transformer-local.h instead, to add your own modifications. header file built by cproto transformer-local.h include file for transformer library prefix used for value entity names; no conflict should occur with user function names as long as they are restricted to 6 characters

Definition at line 38 of file transformer.h.

◆ SEMANTICS_SEPARATOR

#define SEMANTICS_SEPARATOR   '#'

Must be used in suffixes and prefixes below.

Definition at line 41 of file transformer.h.

◆ SIZEOF_SUFFIX

#define SIZEOF_SUFFIX   "#sizeof"

Definition at line 58 of file transformer.h.

◆ TEMPORARY_VALUE_PREFIX

#define TEMPORARY_VALUE_PREFIX   "t#"

Definition at line 47 of file transformer.h.

Function Documentation

◆ active_transformer_list_to_transformer()

transformer active_transformer_list_to_transformer ( list  ltl)

Reduce the sublist of active transformers in the transformer list ltl to one transformer using the convex hull operator.

An active transformer is a transformer with argument(s): at least one value is changed.

Note: a hidden identity transformer such as T(i) {i==i::init} is not detected.

Parameters
ltltl

Definition at line 447 of file transformer_list.c.

448 {
449  return generic_transformer_list_to_transformer(ltl, true);
450 }
transformer generic_transformer_list_to_transformer(list ltl, bool active_p)
Reduce the transformer list with the convex hull operator.

References generic_transformer_list_to_transformer().

Referenced by transformer_list_closure_to_precondition_depth_two(), transformer_list_closure_to_precondition_max_depth(), and whileloop_to_postcondition().

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

◆ add_address_of_value()

void add_address_of_value ( reference  r,
type  t 
)

add the couple (e, address_of_value)

add its name

Definition at line 1309 of file value.c.

1310 {
1311  pips_internal_error("Obsolete function.\n");
1312  entity e = reference_variable(r);
1313  entity address_of_value;
1314  string address_of_value_name;
1315  string indice = strstr(reference_to_string(r), "[");
1316 
1317  if (indice != NULL)
1318  address_of_value_name = concatenate(
1319  entity_name(e), indice, ADDRESS_OF_SUFFIX, (char *) NULL);
1320  else
1321  address_of_value_name = concatenate(
1322  entity_name(e), ADDRESS_OF_SUFFIX, (char *) NULL);
1323 
1324 
1325  //address_of_value = gen_find_entity(address_of_value_name);
1326  address_of_value = gen_find_tabulated(address_of_value_name, entity_domain);
1327  //if (entity_undefined_p(address_of_value))
1328  if(address_of_value == entity_undefined)
1329  address_of_value = make_entity(strdup(address_of_value_name),
1330  copy_type(t),
1332  value_undefined);
1333 
1334  /* add the couple (e, address_of_value) */
1336  hash_put(hash_reference_to_address_of_value, (char *) r, (char *) address_of_value);
1337  /* add its name */
1338  hash_put(hash_value_to_name, (char *) address_of_value,
1339  strdup(entity_name(address_of_value)));
1340  // The next table be reset after the analysis, can't be reuse for the prettyprint, so useless to add in the table?
1341  entity v = value_to_variable(address_of_value);
1342  hash_put(hash_entity_to_user_value_name, (char *) address_of_value,
1343  strdup(concatenate("&", entity_user_name(v), indice, (char *) NULL)));
1344  }
1345 }
type copy_type(type p)
TYPE.
Definition: ri.c:2655
storage make_storage(enum storage_utype tag, void *val)
Definition: ri.c:2273
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:449
void hash_put(hash_table htp, const void *key, const void *val)
This functions stores a couple (key,val) in the hash table pointed to by htp.
Definition: hash.c:364
#define pips_internal_error
Definition: misc-local.h:149
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define HASH_UNDEFINED_VALUE
value returned by hash_get() when the key is not found; could also be called HASH_KEY_NOT_FOUND,...
Definition: newgen_hash.h:56
void * gen_find_tabulated(const char *, int)
Definition: tabulated.c:218
#define UU
Definition: newgen_types.h:98
entity value_to_variable(entity val)
Get the primitive variable associated to any value involved in a transformer.
Definition: value.c:1624
static hash_table hash_reference_to_address_of_value
Definition: value.c:225
static hash_table hash_entity_to_user_value_name
Definition: value.c:223
static hash_table hash_value_to_name
Definition: value.c:222
string reference_to_string(reference r)
Definition: expression.c:87
#define make_entity(n, t, s, i)
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
#define value_undefined
Definition: ri.h:3016
#define reference_variable(x)
Definition: ri.h:2326
@ is_storage_rom
Definition: ri.h:2494
#define entity_undefined
Definition: ri.h:2761
#define entity_name(x)
Definition: ri.h:2790
#define entity_domain
newgen_syntax_domain_defined
Definition: ri.h:410
char * strdup()
#define ADDRESS_OF_SUFFIX

References ADDRESS_OF_SUFFIX, concatenate(), copy_type(), entity_domain, entity_name, entity_undefined, entity_user_name(), gen_find_tabulated(), hash_entity_to_user_value_name, hash_get(), hash_put(), hash_reference_to_address_of_value, HASH_UNDEFINED_VALUE, hash_value_to_name, is_storage_rom, make_entity, make_storage(), pips_internal_error, reference_to_string(), reference_variable, strdup(), UU, value_to_variable(), and value_undefined.

+ Here is the call graph for this function:

◆ add_intermediate_alias_value()

void add_intermediate_alias_value ( entity  e,
entity  a 
)

add_new_value_name(e);

Definition at line 1495 of file value.c.

1496 {
1498 
1499  pips_assert("add_intermediate_alias_valued",
1501  == HASH_UNDEFINED_VALUE));
1502 
1504 
1505  hash_put(hash_entity_to_intermediate_value, (char *) e, (char *) v);
1506  /* add_new_value_name(e); */
1507 }
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
entity entity_to_intermediate_value(entity e)
Definition: value.c:879
static hash_table hash_entity_to_intermediate_value
Definition: value.c:221

References entity_to_intermediate_value(), entity_undefined, hash_entity_to_intermediate_value, hash_get(), hash_put(), HASH_UNDEFINED_VALUE, and pips_assert.

Referenced by add_interprocedural_value_entities().

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

◆ add_intermediate_value()

void add_intermediate_value ( entity  e)

get a new intermediate value, if necessary

add its (external) name

Definition at line 1476 of file value.c.

1477 {
1478  entity intermediate_value;
1479 
1480  /* get a new intermediate value, if necessary */
1481  if((intermediate_value =
1484  intermediate_value = make_local_intermediate_value_entity(entity_type(e));
1486  (char *) intermediate_value);
1487  /* add its (external) name */
1488  hash_put(hash_value_to_name, (char *) intermediate_value,
1491  (char *) NULL)));
1492  }
1493 }
static entity make_local_intermediate_value_entity(type t)
Definition: value.c:600
#define entity_type(x)
Definition: ri.h:2792
#define INTERMEDIATE_VALUE_SUFFIX

References concatenate(), entity_name, entity_type, hash_entity_to_intermediate_value, hash_get(), hash_put(), HASH_UNDEFINED_VALUE, hash_value_to_name, INTERMEDIATE_VALUE_SUFFIX, make_local_intermediate_value_entity(), and strdup().

Referenced by add_interprocedural_value_entities(), add_or_kill_equivalenced_variables(), convex_in_effect_loop_range_fix(), and interlaced_basic_workchunk_regions_p().

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

◆ add_local_intermediate_value()

void add_local_intermediate_value ( entity  e)

get a new intermediate value, if necessary

add its (external) name

Definition at line 1526 of file value.c.

1527 {
1528  entity intermediate_value;
1529 
1530  /* get a new intermediate value, if necessary */
1531  if((intermediate_value =
1534  intermediate_value = make_local_intermediate_value_entity(entity_type(e));
1536  (char *) intermediate_value);
1537  /* add its (external) name */
1538  hash_put(hash_value_to_name, (char *) intermediate_value,
1541  (char *) NULL)));
1542  }
1543 }

References concatenate(), entity_name, entity_type, hash_entity_to_intermediate_value, hash_get(), hash_put(), HASH_UNDEFINED_VALUE, hash_value_to_name, INTERMEDIATE_VALUE_SUFFIX, make_local_intermediate_value_entity(), and strdup().

Referenced by add_intraprocedural_value_entities_unconditionally().

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

◆ add_local_old_value()

void add_local_old_value ( entity  e)

get a new old value, if necessary

add its (external) name

Definition at line 1509 of file value.c.

1510 {
1511  entity old_value;
1512 
1513  /* get a new old value, if necessary */
1514  if((old_value =
1515  (entity) hash_get(hash_entity_to_old_value, (char *) e))
1517  old_value = make_local_old_value_entity(entity_type(e));
1518  hash_put(hash_entity_to_old_value, (char *) e, (char *) old_value);
1519  /* add its (external) name */
1520  hash_put(hash_value_to_name, (char *) old_value,
1522  (char *) NULL)));
1523  }
1524 }
static hash_table hash_entity_to_old_value
Definition: value.c:220
static entity make_local_old_value_entity(type t)
Definition: value.c:595
#define OLD_VALUE_SUFFIX

References concatenate(), entity_name, entity_type, hash_entity_to_old_value, hash_get(), hash_put(), HASH_UNDEFINED_VALUE, hash_value_to_name, make_local_old_value_entity(), OLD_VALUE_SUFFIX, and strdup().

Referenced by add_intraprocedural_value_entities_unconditionally().

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

◆ add_new_alias_value()

void add_new_alias_value ( entity  e,
entity  a 
)

add_new_value_name(e);

Definition at line 1396 of file value.c.

1397 {
1399  pips_debug(8, "begin: for %s and %s\n",
1400  entity_name(e),entity_name(a));
1401  pips_assert("hash_entity_to_new_value is defined",
1402  (hash_get(hash_entity_to_new_value, (char *) e)
1403  == HASH_UNDEFINED_VALUE));
1404 
1405  v = entity_to_new_value(a);
1406 
1407  hash_put(hash_entity_to_new_value, (char *) e, (char *) v);
1408  /* add_new_value_name(e); */
1409 }
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
static hash_table hash_entity_to_new_value
VARIABLE VALUE MANAGEMENT PACKAGE FOR TRANSFORMERS.
Definition: value.c:219
entity entity_to_new_value(entity e)
Definition: value.c:859

References entity_name, entity_to_new_value(), entity_undefined, hash_entity_to_new_value, hash_get(), hash_put(), HASH_UNDEFINED_VALUE, pips_assert, and pips_debug.

Referenced by add_interprocedural_new_value_entity(), and add_interprocedural_value_entities().

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

◆ add_new_value()

void add_new_value ( entity  e)

Definition at line 1386 of file value.c.

1387 {
1388  pips_debug(8,"begin: for %s\n", entity_name(e));
1389  if(hash_get(hash_entity_to_new_value, (char *) e)
1390  == HASH_UNDEFINED_VALUE) {
1391  hash_put(hash_entity_to_new_value, (char *) e, (char *) e);
1392  add_new_value_name(e);
1393  }
1394 }
static void add_new_value_name(entity e)
HASH TABLE INITIALIZATION.
Definition: value.c:1254

References add_new_value_name(), entity_name, hash_entity_to_new_value, hash_get(), hash_put(), HASH_UNDEFINED_VALUE, and pips_debug.

Referenced by add_interprocedural_new_value_entity(), add_interprocedural_value_entities(), add_intraprocedural_value_entities_unconditionally(), and add_or_kill_equivalenced_variables().

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

◆ add_old_alias_value()

void add_old_alias_value ( entity  e,
entity  a 
)

add_new_value_name(e);

Definition at line 1463 of file value.c.

1464 {
1466 
1467  pips_assert("add_old_alias_valued", (hash_get(hash_entity_to_old_value, (char *) e)
1468  == HASH_UNDEFINED_VALUE));
1469 
1470  v = entity_to_old_value(a);
1471 
1472  hash_put(hash_entity_to_old_value, (char *) e, (char *) v);
1473  /* add_new_value_name(e); */
1474 }
entity entity_to_old_value(entity e)
Definition: value.c:869

References entity_to_old_value(), entity_undefined, hash_entity_to_old_value, hash_get(), hash_put(), HASH_UNDEFINED_VALUE, and pips_assert.

Referenced by add_interprocedural_value_entities().

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

◆ add_old_value()

void add_old_value ( entity  e)

find the old value entity if possible, else, generate it

add the couple (e, old_value)

add its name

Definition at line 1440 of file value.c.

1441 {
1442  entity old_value;
1443  string old_value_name;
1444 
1445  /* find the old value entity if possible, else, generate it */
1446  old_value_name = concatenate(entity_name(e),OLD_VALUE_SUFFIX,
1447  (char *) NULL);
1448  old_value = gen_find_tabulated(old_value_name, entity_domain);
1449  if(old_value == entity_undefined)
1450  old_value = make_entity(strdup(old_value_name),
1451  copy_type(entity_type(e)),
1453  value_undefined);
1454  /* add the couple (e, old_value) */
1456  hash_put(hash_entity_to_old_value, (char *) e, (char *) old_value);
1457  /* add its name */
1458  hash_put(hash_value_to_name, (char *) old_value,
1459  strdup(entity_name(old_value)));
1460  }
1461 }

References concatenate(), copy_type(), entity_domain, entity_name, entity_type, entity_undefined, gen_find_tabulated(), hash_entity_to_old_value, hash_get(), hash_put(), HASH_UNDEFINED_VALUE, hash_value_to_name, is_storage_rom, make_entity, make_storage(), OLD_VALUE_SUFFIX, strdup(), UU, and value_undefined.

Referenced by add_interprocedural_value_entities(), add_or_kill_equivalenced_variables(), and add_synonym_values().

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

◆ add_sizeof_value()

void add_sizeof_value ( type  t)

For a given architecture, sizeof(t) is a constant.

It has no old value, no new value, it is a value.

Constants are encoded as 0-ary functions, not as values.

find the sizeof entity if possible, else, generate it

add the couple (e, old_value)

add its name

Definition at line 1352 of file value.c.

1353 {
1354  entity sizeof_value;
1355  string sizeof_value_name;
1356 
1357  // improvement create the entity with the name of type
1358  // issue because of value_to_variable
1359  /* find the sizeof entity if possible, else, generate it */
1360  sizeof_value_name =
1361  concatenate(
1363  type_to_full_string_definition(t), SIZEOF_SUFFIX, (char *) NULL);
1364  sizeof_value = gen_find_tabulated(sizeof_value_name, entity_domain);
1365  if(sizeof_value == entity_undefined)
1366  sizeof_value =
1367  make_entity(strdup(sizeof_value_name),
1368  //make_type(is_type_variable,
1369  // make_variable(make_basic(is_basic_int, (void*)sizeof(int)),NIL,NIL)),
1370  copy_type(t),
1372  value_undefined);
1373  /* add the couple (e, old_value) */
1375  hash_put(hash_type_to_sizeof_value, (char *) t, (char *) sizeof_value);
1376  /* add its name */
1377  hash_put(hash_value_to_name, (char *) sizeof_value,
1378  strdup(entity_name(sizeof_value)));
1379  hash_put(hash_entity_to_new_value, (char *) sizeof_value,
1380  (char *) sizeof_value);
1381  hash_put(hash_entity_to_user_value_name, (char *) sizeof_value,
1382  concatenate("sizeof(", type_to_full_string_definition(t), ")", (char *) NULL));
1383  }
1384 }
#define TOP_LEVEL_MODULE_NAME
Module containing the global variables in Fortran and C.
Definition: naming-local.h:101
#define MODULE_SEP_STRING
Definition: naming-local.h:30
static hash_table hash_type_to_sizeof_value
Definition: value.c:227
string type_to_full_string_definition(type)
type.c
Definition: type.c:45
#define SIZEOF_SUFFIX

References concatenate(), copy_type(), entity_domain, entity_name, entity_undefined, gen_find_tabulated(), hash_entity_to_new_value, hash_entity_to_user_value_name, hash_get(), hash_put(), hash_type_to_sizeof_value, HASH_UNDEFINED_VALUE, hash_value_to_name, is_storage_rom, make_entity, make_storage(), MODULE_SEP_STRING, SIZEOF_SUFFIX, strdup(), TOP_LEVEL_MODULE_NAME, type_to_full_string_definition(), UU, and value_undefined.

Referenced by expression_multiply_sizeof_to_transformer().

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

◆ add_synonym_values()

void add_synonym_values ( entity  e,
entity  eq,
bool  readonly 
)

e and eq are entities whose values are always equal because they share the exact same memory location (i.e. they are alias). Values for e have already been declared. Values for eq have to be declared.

hash_put(hash_value_to_name, (char *) old_value_eq, entity_name(old_value_eq));

The name does not change. It is not used until the equivalence equations are added

Parameters
eqq
readonlyeadonly

Definition at line 1578 of file value.c.

1579 {
1580  /* e and eq are entities whose values are always equal because they
1581  * share the exact same memory location (i.e. they are alias). Values
1582  * for e have already been declared. Values for eq have to be
1583  * declared. */
1584  entity new_value = entity_to_new_value(e);
1585  entity intermediate_value;
1586 
1587  pips_debug(8, "Begin for registered variable %s"
1588  " equivalenced with new variable %s"
1589  " with status %s\n",
1591  readonly? "readonly" : "read/write");
1592 
1594  (char *) new_value);
1595  if(!readonly) {
1596  entity old_value = entity_to_old_value(e);
1597  intermediate_value = entity_to_intermediate_value(e);
1598  add_old_value(eq);
1600  (char *) intermediate_value);
1602  (char *) old_value);
1603  /* hash_put(hash_value_to_name, (char *) old_value_eq, entity_name(old_value_eq)); */
1604  }
1605  /* The name does not change. It is not used until the equivalence
1606  equations are added */
1607  hash_put(hash_value_to_name, (char *) eq,
1609  NEW_VALUE_SUFFIX, (char *) NULL)));
1610 
1611  pips_debug(8, "End\n");
1612 }
void hash_update(hash_table htp, const void *key, const void *val)
update key->val in htp, that MUST be pre-existent.
Definition: hash.c:491
void add_old_value(entity e)
Definition: value.c:1440
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
Pcontrainte eq
element du vecteur colonne du systeme donne par l'analyse
Definition: sc_gram.c:108
#define NEW_VALUE_SUFFIX
external suffixes (NEW_VALUE_SUFFIX is not used, new values are represented by the variable itself,...

References add_old_value(), concatenate(), entity_local_name(), entity_name, entity_to_intermediate_value(), entity_to_new_value(), entity_to_old_value(), eq, hash_entity_to_intermediate_value, hash_entity_to_new_value, hash_entity_to_old_value, hash_put(), hash_update(), hash_value_to_name, NEW_VALUE_SUFFIX, pips_debug, and strdup().

Referenced by add_equivalenced_values().

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

◆ add_value_to_transformer_space()

void add_value_to_transformer_space ( entity  v,
transformer  tf 
)
Parameters
tff

Definition at line 859 of file basic.c.

860 {
863  return;
864 }
#define transformer_relation(x)
Definition: ri.h:2873
#define predicate_system(x)
Definition: ri.h:2069
void sc_base_add_variable(Psysteme sc, Variable var)
Definition: sc.c:248
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 predicate_system, sc_base_add_variable(), and transformer_relation.

Referenced by transformer_add_variable_type_information().

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

◆ address_of_value_entity_p()

bool address_of_value_entity_p ( entity  e)

Definition at line 962 of file value.c.

963 {
964  string s = strstr(entity_local_name(e), ADDRESS_OF_SUFFIX);
965 
966  return s!=NULL;
967 }

References ADDRESS_OF_SUFFIX, and entity_local_name().

Referenced by pips_user_value_name(), and value_to_variable().

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

◆ allocate_value_mappings()

void allocate_value_mappings ( int  n,
int  o,
int  i 
)

hash_warn_on_redefinition();

Definition at line 1165 of file value.c.

1166 {
1167  pips_assert("undefined mappings for allocation",
1174 
1175  /* hash_warn_on_redefinition(); */
1181  hash_table_make(hash_pointer, n + o + i + n); // The last +n for the pointer
1183  hash_table_make(hash_pointer, n + o + i + n); // The last +n for the pointer
1186 }
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
@ hash_pointer
Definition: newgen_hash.h:32
#define hash_table_undefined_p(h)
Definition: newgen_hash.h:50

References hash_entity_to_intermediate_value, hash_entity_to_new_value, hash_entity_to_old_value, hash_entity_to_user_value_name, hash_pointer, hash_reference_to_address_of_value, hash_table_make(), hash_table_undefined_p, hash_type_to_sizeof_value, hash_value_to_name, and pips_assert.

Referenced by allocate_module_value_mappings().

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

◆ analyzable_scalar_entity_p()

bool analyzable_scalar_entity_p ( entity  e)

The entity type is one of the analyzed types.

Definition at line 471 of file value.c.

472 {
473  bool result = false;
474 
475  if(!abstract_state_variable_p(e) // for packages such as IO or RAND
476  && !typedef_entity_p(e)
479  && !place_holder_variable_p(e)) { // Because enum are analyzed
481  result = analyzed_type_p(bct);
482  }
483  return result;
484 }
bool entity_heap_location_p(entity b)
package abstract location.
bool entity_typed_anywhere_locations_p(entity e)
Test if an entity is the bottom of the lattice.
bool analyzed_type_p(type t)
The type t is one of the analyzed types.
Definition: value.c:367
bool typedef_entity_p(entity e)
Definition: entity.c:1902
bool abstract_state_variable_p(entity v)
Definition: entity.c:2572
bool place_holder_variable_p(entity)
Definition: variable.c:2069
type entity_basic_concrete_type(entity)
retrieves or computes and then returns the basic concrete type of an entity
Definition: type.c:3677

References abstract_state_variable_p(), analyzed_type_p(), entity_basic_concrete_type(), entity_heap_location_p(), entity_typed_anywhere_locations_p(), place_holder_variable_p(), and typedef_entity_p().

Referenced by add_implicit_interprocedural_write_effects(), add_or_kill_equivalenced_variables(), any_user_call_site_to_transformer(), c_return_to_transformer(), external_entity_to_new_value(), generic_reference_to_transformer(), module_to_formal_analyzable_parameters(), module_to_value_mappings(), precondition_intra_to_inter(), and same_analyzable_type_scalar_entity_list_p().

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

◆ analyzed_array_p()

bool analyzed_array_p ( entity  a)

Does array a contain directly or indirectly a field that may be analyzable?

Definition at line 434 of file value.c.

435 {
436  bool analyzed_p = false;
439  if(analyzed_type_p(et))
440  analyzed_p = true;
441  else if(struct_type_p(et))
442  analyzed_p = analyzed_struct_type_p(et);
443  return analyzed_p;
444 }
bool analyzed_struct_type_p(type st)
Definition: value.c:406
bool struct_type_p(type)
Returns true if t is of type derived and if the derived type is a struct.
Definition: type.c:3121
type array_type_to_element_type(type)
returns the type of the elements of an array type, as a newly allocated type.
Definition: type.c:5700

References analyzed_struct_type_p(), analyzed_type_p(), array_type_to_element_type(), entity_basic_concrete_type(), and struct_type_p().

+ Here is the call graph for this function:

◆ analyzed_array_type_p()

bool analyzed_array_type_p ( type  at)
Parameters
att

Definition at line 446 of file value.c.

447 {
448  bool analyzed_p = false;
450  if(analyzed_type_p(et))
451  analyzed_p = true;
452  else if(struct_type_p(et))
453  analyzed_p = analyzed_struct_type_p(et);
454  return analyzed_p;
455 }

References analyzed_struct_type_p(), analyzed_type_p(), array_type_to_element_type(), and struct_type_p().

Referenced by analyzed_entity_p(), and analyzed_struct_type_p().

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

◆ analyzed_basic_p()

bool analyzed_basic_p ( basic  b)

The basic corresponds to one of the analyzed types.

Definition at line 337 of file value.c.

338 {
339  bool analyzed_p = false;
340 
342  analyzed_p = true;
344  analyzed_p = true;
346  analyzed_p = true;
348  analyzed_p = true;
350  pips_debug(9,"pointer type : %s\n", type_to_string(basic_pointer(b)));
351  analyzed_p = true;
352  }
354  analyzed_p = true;
356  entity de = basic_derived(b);
358  analyzed_p = type_enum_p(dt);
359  }
360  else
361  analyzed_p = false;
362 
363  return analyzed_p;
364 }
static bool analyze_string_scalar_entities
Definition: value.c:264
static bool analyze_integer_scalar_entities
TYPING.
Definition: value.c:262
static bool analyze_boolean_scalar_entities
Definition: value.c:263
static bool analyze_complex_scalar_entities
Definition: value.c:266
static bool analyze_float_scalar_entities
Definition: value.c:265
static bool analyze_pointer_scalar_entities
Definition: value.c:267
string type_to_string(const type)
type.c
Definition: type.c:51
#define type_enum_p(x)
Definition: ri.h:2968
#define basic_pointer(x)
Definition: ri.h:637
#define basic_complex_p(x)
Definition: ri.h:626
#define basic_int_p(x)
Definition: ri.h:614
#define basic_derived(x)
Definition: ri.h:640
#define basic_pointer_p(x)
Definition: ri.h:635
#define basic_derived_p(x)
Definition: ri.h:638
#define basic_string_p(x)
Definition: ri.h:629
#define basic_logical_p(x)
Definition: ri.h:620
#define basic_float_p(x)
Definition: ri.h:617

References analyze_boolean_scalar_entities, analyze_complex_scalar_entities, analyze_float_scalar_entities, analyze_integer_scalar_entities, analyze_pointer_scalar_entities, analyze_string_scalar_entities, basic_complex_p, basic_derived, basic_derived_p, basic_float_p, basic_int_p, basic_logical_p, basic_pointer, basic_pointer_p, basic_string_p, entity_basic_concrete_type(), pips_debug, type_enum_p, and type_to_string().

Referenced by analyzed_type_p(), and condition_to_transformer().

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

◆ analyzed_constant_p()

bool analyzed_constant_p ( entity  f)

The constant may appear as a variable in the linear systems.

is f a 0-ary function, i.e. a constant of proper type?

integer and logical constants are handled explicitly

Definition at line 487 of file value.c.

488 {
489  /* is f a 0-ary function, i.e. a constant of proper type? */
490  if(entity_constant_p(f)) {
493 
494  /* integer and logical constants are handled explicitly */
495 
497  return true;
499  return true;
501  return true;
503  return true;
504  }
505  return false;
506 }
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
#define entity_constant_p(e)
#define functional_result(x)
Definition: ri.h:1444
#define type_functional(x)
Definition: ri.h:2952
#define type_variable(x)
Definition: ri.h:2949
#define variable_basic(x)
Definition: ri.h:3120

References analyze_complex_scalar_entities, analyze_float_scalar_entities, analyze_pointer_scalar_entities, analyze_string_scalar_entities, basic_complex_p, basic_float_p, basic_pointer_p, basic_string_p, entity_constant_p, entity_type, f(), functional_result, type_functional, type_variable, and variable_basic.

Referenced by value_mappings_compatible_vector_p().

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

◆ analyzed_entity_p()

bool analyzed_entity_p ( entity  e)

Definition at line 457 of file value.c.

458 {
459  bool analyzed_p = false;
461  if(analyzed_type_p(et))
462  analyzed_p = true;
463  else if(struct_type_p(et))
464  analyzed_p = analyzed_struct_type_p(et);
465  else if(array_type_p(et))
466  analyzed_p = analyzed_array_type_p(et);
467  return analyzed_p;
468 }
bool analyzed_array_type_p(type at)
Definition: value.c:446
bool array_type_p(type)
Definition: type.c:2942

References analyzed_array_type_p(), analyzed_struct_type_p(), analyzed_type_p(), array_type_p(), entity_basic_concrete_type(), and struct_type_p().

Referenced by generic_substitute_formal_array_elements_in_transformer().

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

◆ analyzed_reference_p()

bool analyzed_reference_p ( reference  r)

FI: Nelson explains the motivation for can_be_constant_path_p() but I do not understand them.

He also explains the motivation for strict_constant_path_p() and I do not understand them either.

Stricly speaking, this funtion should be called analyzed_points_to_reference_p()

Definition at line 518 of file value.c.

519 {
520  pips_debug(7, "analyzed_reference_p, ref : %s\n", reference_to_string(r));
521  bool result = false;
522  entity v = reference_variable(r);
523 
525  //&& atomic_points_to_reference_p(r)) {
527  && !effects_package_entity_p(v)) {
529  result = analyzed_type_p(t);
530  }
531  else {
532  // e.g. a[i]
533  result = false;
534  }
535 
536  pips_debug(7, "analyzed_reference_p result : %i\n", result);
537  return result;
538 }
type points_to_reference_to_concrete_type(reference)
Definition: type.c:685
bool generic_atomic_points_to_reference_p(reference, bool)
Is it a unique concrete memory location?
Definition: points_to.c:489
bool store_independent_points_to_reference_p(reference)
Functions for points-to references, the kind of references used in points-to cells.
Definition: points_to.c:1247
bool effects_package_entity_p(entity e)
checks if an entity is an IO_EFFECTS_PACKAGE_NAME, a MALLOC_EFFECTS_NAME or a RAND_EFFECTS_PACKAGE_NA...
Definition: entity.c:1181

References analyzed_type_p(), effects_package_entity_p(), generic_atomic_points_to_reference_p(), pips_debug, points_to_reference_to_concrete_type(), reference_to_string(), reference_variable, and store_independent_points_to_reference_p().

Referenced by any_assign_to_transformer(), any_basic_update_to_transformer(), any_update_to_transformer(), assign_rhs_to_reflhs_to_transformer(), generic_apply_effect_to_transformer(), lhs_expression_to_transformer(), module_to_value_mappings(), points_to_unary_operation_to_transformer(), and substitute_stubs_in_transformer().

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

◆ analyzed_struct_p()

bool analyzed_struct_p ( entity  s)

Does struct s contain directly or indirectly a field that may be analyzable?

Definition at line 387 of file value.c.

388 {
389  bool analyzed_p = false;
391  FOREACH(ENTITY, f, fl) {
393  if(analyzed_type_p(ft)) {
394  analyzed_p = true;
395  break;
396  }
397  else if(struct_type_p(ft)) {
398  analyzed_p = analyzed_struct_p(f);
399  if(analyzed_p)
400  break;
401  }
402  }
403  return analyzed_p;
404 }
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
bool analyzed_struct_p(entity s)
Does struct s contain directly or indirectly a field that may be analyzable?
Definition: value.c:387
list struct_variable_to_fields(entity)
Assume that v is declared as a struct.
Definition: variable.c:2045
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References analyzed_struct_p(), analyzed_type_p(), ENTITY, entity_basic_concrete_type(), f(), FOREACH, struct_type_p(), and struct_variable_to_fields().

Referenced by analyzed_struct_p().

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

◆ analyzed_struct_type_p()

bool analyzed_struct_type_p ( type  st)
Parameters
stt

Definition at line 406 of file value.c.

407 {
408  bool analyzed_p = false;
409  list fl = struct_type_to_fields(st);
410  FOREACH(ENTITY, f, fl) {
411  // FI: might be shorter an safer to call entity_analyzed_p(f)
413  if(analyzed_type_p(ft)) {
414  analyzed_p = true;
415  break;
416  }
417  else if(struct_type_p(ft)) {
418  analyzed_p = analyzed_struct_type_p(ft);
419  if(analyzed_p)
420  break;
421  }
422  else if(array_type_p(ft)) {
423  analyzed_p = analyzed_array_type_p(ft);
424  if(analyzed_p)
425  break;
426  }
427  }
428  return analyzed_p;
429 }
list struct_type_to_fields(type)
Definition: type.c:5798

References analyzed_array_type_p(), analyzed_struct_type_p(), analyzed_type_p(), array_type_p(), ENTITY, entity_basic_concrete_type(), f(), FOREACH, struct_type_p(), and struct_type_to_fields().

Referenced by analyzed_array_p(), analyzed_array_type_p(), analyzed_entity_p(), and analyzed_struct_type_p().

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

◆ analyzed_type_p()

bool analyzed_type_p ( type  t)

The type t is one of the analyzed types.

Definition at line 367 of file value.c.

368 {
369  bool result = false;
371 
372  if(type_variable_p(bct)) {
373  variable v = type_variable(bct);
374  if (!volatile_variable_p(v)
375  && ENDP(variable_dimensions(v)) //NL : for checking the dimension instead of entity_scalar_p which filter pointer type
376  ) {
377  result = analyzed_basic_p(variable_basic(v));
378  }
379  }
380 
381  return result;
382 }
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
bool analyzed_basic_p(basic b)
The basic corresponds to one of the analyzed types.
Definition: value.c:337
type compute_basic_concrete_type(type)
computes a new type which is the basic concrete type of the input type (this new type is not stored i...
Definition: type.c:3556
bool volatile_variable_p(variable)
Definition: variable.c:1649
#define variable_dimensions(x)
Definition: ri.h:3122
#define type_variable_p(x)
Definition: ri.h:2947

References analyzed_basic_p(), compute_basic_concrete_type(), ENDP, type_variable, type_variable_p, variable_basic, variable_dimensions, and volatile_variable_p().

Referenced by add_inter_or_intraprocedural_field_entities(), analyzable_scalar_entity_p(), analyzed_array_p(), analyzed_array_type_p(), analyzed_entity_p(), analyzed_reference_p(), analyzed_struct_p(), analyzed_struct_type_p(), assign_rhs_to_reflhs_to_transformer(), call_to_transformer(), create_values_for_simple_effect(), expression_to_transformer(), generic_reference_to_transformer(), generic_substitute_formal_array_elements_in_transformer(), make_local_temporary_value_entity(), module_to_value_mappings(), perform_array_element_substitutions_in_transformer(), semantics_usable_points_to_reference_p(), substitute_struct_stub_in_transformer(), and transformer_apply_field_assignments_or_equalities().

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

◆ any_transformer_to_k_closure()

transformer any_transformer_to_k_closure ( transformer  t_init,
transformer  t_enter,
transformer  t_next,
transformer  t_body,
transformer  post_init,
int  k,
bool  assume_previous_iteration_p 
)

Derived from any_loop_to_k_transformer()

The recursive computation of the loop transformer is not performed here.

Complete the body transformer with t_next (t_body is modified by side effects into t_fbody)

Compute the fix point

Compute t_body_star = t_init ; t_enter

and add the continuation condition, pre_iteration improved with knowledge about the body, npre_iteration. Note that pre_iteration would also provide correct results, although less accurate.

FI: this is a very strong normalization

obvious redundancy like 0<=x, x<=y, 0<=y is detected

Integer redundancy elimination is aso used and leads potentially to larger coefficients and ultimately to an accuracy reduction when a convex hull is performed.

Any transformer or other data structure to free?

Parameters
t_init_init
t_enter_enter
t_next_next
t_body_body
post_initost_init
assume_previous_iteration_pssume_previous_iteration_p

Definition at line 1304 of file fix_point.c.

1320 {
1321  transformer t_fbody = transformer_undefined; // t_body; t_next
1322  transformer t_fbody_star = transformer_undefined; // t_fbody*
1323  transformer t_body_star = transformer_undefined; // t_init ; t_enter ; tfbodystar
1324  transformer post_enter = transformer_apply(t_enter, post_init);
1325  transformer enter_condition = transformer_range(post_enter);
1326  transformer next_condition = transformer_range(t_next);
1327  transformer post_next = transformer_undefined;
1328  //transformer pre_iteration = transformer_convex_hull(enter_condition, next_condition);
1329  transformer npre_iteration = transformer_undefined;
1330  transformer post_loop_star = transformer_undefined;
1331  transformer post_loop_plus = transformer_undefined;
1332  transformer post_loop = transformer_undefined;
1333  transformer t_next_star = transformer_undefined;
1334  transformer t_fbody_k = transformer_undefined;
1335  int ck; // used to unroll k-1 times the loop body
1336 
1337  ifdebug(8) {
1338  fprintf(stderr, "t_init:\n");
1339  print_transformer(t_init);
1340  fprintf(stderr, "t_enter:\n");
1341  print_transformer(t_enter);
1342  fprintf(stderr, "t_next:\n");
1343  print_transformer(t_next);
1344  fprintf(stderr, "t_body:\n");
1345  print_transformer(t_body);
1346  fprintf(stderr, "post_init:\n");
1347  print_transformer(post_init);
1348  }
1349 
1350  if(assume_previous_iteration_p)
1351  t_body = transformer_intersect_range_with_domain(t_body);
1352 
1353  /* Complete the body transformer with t_next (t_body is modified by
1354  side effects into t_fbody) */
1355  t_fbody = transformer_combine(t_body, t_next);
1356 
1357  /* Compute the fix point */
1358  t_fbody_k = copy_transformer(t_fbody);
1359  for(ck=2; ck<=k; ck++)
1360  t_fbody_k = transformer_combine(t_fbody_k, t_fbody);
1361  t_fbody_star = (* transformer_fix_point_operator)(t_fbody_k);
1362  free_transformer(t_fbody_k);
1363 
1364  /* Compute t_body_star = t_init ; t_enter */
1365  t_body_star = transformer_combine(transformer_dup(t_init), t_enter);
1366  t_body_star = transformer_combine(t_body_star, t_fbody_star);
1367 
1368  /* and add the continuation condition, pre_iteration improved with
1369  knowledge about the body, npre_iteration. Note that pre_iteration
1370  would also provide correct results, although less accurate. */
1371  post_loop_star = transformer_apply(t_fbody_star, enter_condition);
1372  post_loop_plus = transformer_apply(t_fbody, post_loop_star);
1373  post_loop = transformer_range(post_loop_plus);
1374  npre_iteration = transformer_convex_hull(enter_condition, post_loop);
1375  if(k==2) { // Should be a loop over k
1376  transformer post_loop_plus_plus = transformer_apply(t_fbody, post_loop_plus);
1377  transformer old_npre_iteration = npre_iteration;
1378  post_loop = transformer_range(post_loop_plus_plus);
1379  npre_iteration = transformer_convex_hull(npre_iteration, post_loop);
1380  free_transformer(post_loop_plus_plus);
1381  free_transformer(old_npre_iteration);
1382  }
1383  t_body_star = transformer_combine(t_body_star, npre_iteration);
1384  /* FI: this is a very strong normalization
1385  *
1386  * obvious redundancy like 0<=x, x<=y, 0<=y is detected
1387  *
1388  * Integer redundancy elimination is aso used and leads potentially
1389  * to larger coefficients and ultimately to an accuracy reduction
1390  * when a convex hull is performed.
1391  */
1392  // FI: I remove it for the time being because it slows down PIPS a lot
1393  // according to measurements for NSAD2014, nested01-09.c
1394  // t_body_star = transformer_normalize(t_body_star, 0);
1395  // Not sufficient for the simple case in Semantics-New/do01
1396  // t_body_star = transformer_normalize(t_body_star, 2);
1397 
1398  /* Any transformer or other data structure to free? */
1399  //free_transformer(t_body); transformed into t_fbody
1400  free_transformer(t_fbody);
1401  free_transformer(t_fbody_star);
1402  free_transformer(post_next);
1403  //free_transformer(t_effects);
1404  free_transformer(post_enter);
1405  free_transformer(enter_condition);
1406  free_transformer(next_condition);
1407  free_transformer(npre_iteration);
1408  free_transformer(post_loop_star);
1409  free_transformer(post_loop_plus);
1410  free_transformer(post_loop);
1411  free_transformer(t_next_star);
1412 
1413  ifdebug(8) {
1414  fprintf(stderr, "t_body_star:\n");
1415  print_transformer(t_body_star);
1416  }
1417 
1418  return t_body_star;
1419 }
void free_transformer(transformer p)
Definition: ri.c:2616
transformer copy_transformer(transformer p)
TRANSFORMER.
Definition: ri.c:2613
transformer transformer_dup(transformer t_in)
transformer package - basic routines
Definition: basic.c:49
#define print_transformer(t)
Definition: print.c:357
#define transformer_undefined
Definition: ri.h:2847
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
#define ifdebug(n)
Definition: sg.c:47
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
transformer transformer_intersect_range_with_domain(transformer tf)
When tf is used repeatedly in a loop, the range is part of the domain from iteration 2 to the end.
Definition: transformer.c:845
transformer transformer_combine(volatile transformer t1, transformer t2)
transformer transformer_combine(transformer t1, transformer t2): compute the composition of transform...
Definition: transformer.c:238
transformer transformer_apply(transformer tf, transformer pre)
transformer transformer_apply(transformer tf, transformer pre): apply transformer tf on precondition ...
Definition: transformer.c:1559
transformer transformer_range(transformer tf)
Return the range of relation tf in a newly allocated transformer.
Definition: transformer.c:714

References copy_transformer(), fprintf(), free_transformer(), ifdebug, print_transformer, transformer_apply(), transformer_combine(), transformer_convex_hull(), transformer_dup(), transformer_intersect_range_with_domain(), transformer_range(), and transformer_undefined.

Referenced by any_loop_to_k_transformer().

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

◆ apply_transformer_lists()

list apply_transformer_lists ( list  tl1,
list  tl2 
)
Parameters
tl1l1
tl2l2

Definition at line 269 of file transformer_list.c.

270 {
271  return apply_transformer_lists_generic(tl1, tl2, false);
272 }
list apply_transformer_lists_generic(list tl1, list tl2, bool exclude_p)
each transformer of tl1 must be applied to each precondition of tl2, including the identity transform...

References apply_transformer_lists_generic().

+ Here is the call graph for this function:

◆ apply_transformer_lists_generic()

list apply_transformer_lists_generic ( list  tl1,
list  tl2,
bool  exclude_p 
)

each transformer of tl1 must be applied to each precondition of tl2, including the identity transformer.

If an identity transformer is generated and if identity transformers are always first in the list, it will again be first in the returned list. Empty preconditions are not preserved in the returned list. An empty list is unfeasible.

if exclude_p==false, return U_i1 U_i2 apply(t_i1, p_i2); else return U_i1 U_i2!=i1 apply(t_i1, p_i2);

Parameters
tl1l1
tl2l2
exclude_pxclude_p

Definition at line 223 of file transformer_list.c.

224 {
225  list ntl = NIL;
226  int n1 = gen_length(tl1);
227  int n2 = gen_length(tl2);
228  int en = 0; // number of empty preconditions generated
229  int sn = 0; // number of excluded/skipped preconditions
230  int nn = -1; // number of preconditions in the result
231  int i1 = 0;
232 
233  // FI: not true is option keep_p has been used to maintain
234  //|tl_1|==|tl_2| which is useful when exclude_p is TRUE
235  if(!exclude_p) {
236  pips_assert("tl1 is OK\n", check_transformer_list(tl1));
237  pips_assert("tl2 is OK\n", check_transformer_list(tl2));
238  }
239 
240  FOREACH(TRANSFORMER, t1, tl1) {
241  int i2 = 0;
242  i1++;
243  FOREACH(TRANSFORMER, t2, tl2) {
244  i2++;
245  if(i1!=i2 && exclude_p) {
246  transformer nt = transformer_apply(t1, t2);
247 
248  if(!transformer_empty_p(nt))
249  ntl = CONS(TRANSFORMER, nt, ntl);
250  else
251  en++;
252  }
253  else if(exclude_p)
254  sn++;
255  }
256  }
257  ntl = gen_nreverse(ntl);
258 
259  nn = gen_length(ntl);
260  pips_assert("nn is n1*n2-en", nn==n1*n2-en-sn);
261  //FI: there is no guarantee here that the identity transformer is
262  //not returned multiple times... although it would make sense if the
263  //input lists are properly sorted.
264  pips_assert("ntl is OK\n", check_transformer_list(ntl));
265 
266  return ntl;
267 }
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
size_t gen_length(const list l)
Definition: list.c:150
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
#define TRANSFORMER(x)
TRANSFORMER.
Definition: ri.h:2841
bool transformer_empty_p(transformer t)
If true is returned, the transformer certainly is empty.
Definition: transformer.c:2455
bool check_transformer_list(list tl)
What do we want to impose?

References check_transformer_list(), CONS, FOREACH, gen_length(), gen_nreverse(), NIL, pips_assert, TRANSFORMER, transformer_apply(), and transformer_empty_p().

Referenced by apply_transformer_lists(), and apply_transformer_lists_with_exclusion().

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

◆ apply_transformer_lists_with_exclusion()

list apply_transformer_lists_with_exclusion ( list  tl1,
list  tl2 
)
Parameters
tl1l1
tl2l2

Definition at line 274 of file transformer_list.c.

275 {
276  return apply_transformer_lists_generic(tl1, tl2, true);
277 }

References apply_transformer_lists_generic().

Referenced by transformer_list_closure_to_precondition_depth_two(), and transformer_list_closure_to_precondition_max_depth().

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

◆ aproximate_number_of_analyzed_variables()

int aproximate_number_of_analyzed_variables ( void  )

FI: I do not know if equivalenced variables are well taken into account

Definition at line 1153 of file value.c.

1154 {
1155  /* FI: I do not know if equivalenced variables are well taken into account*/
1157 }
int hash_table_entry_count(hash_table htp)
now we define observers in order to hide the hash_table type...
Definition: hash.c:818

References hash_entity_to_new_value, and hash_table_entry_count().

Referenced by module_to_value_mappings().

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

◆ args_to_transformer()

transformer args_to_transformer ( list  le)

Generates a transformer abstracting a totally unknown modification of the values associated to variables in list le.

list of entities

Parameters
lee

Definition at line 1907 of file transformer.c.

1908 {
1910  cons * args = transformer_arguments(tf);
1911  Pbase b = VECTEUR_NUL;
1912  Psysteme s = sc_new();
1913 
1914  MAPL(ce, {
1915  entity e = ENTITY(CAR(ce));
1916  entity new_val = entity_to_new_value(e);
1917 
1918  args = arguments_add_entity(args, new_val);
1919  b = vect_add_variable(b, (Variable) new_val);
1920  }, le);
1921 
1922  transformer_arguments(tf) = args;
1923  s->base = b;
1924  s->dimension = vect_size(b);
1926  return tf;
1927 }
cons * arguments_add_entity(cons *a, entity e)
Definition: arguments.c:85
Pbase vect_add_variable(Pbase b, Variable v)
package vecteur - routines sur les bases
Definition: base.c:61
transformer transformer_identity()
Allocate an identity transformer.
Definition: basic.c:110
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define MAPL(_map_list_cp, _code, _l)
Apply some code on the addresses of all the elements of a list.
Definition: newgen_list.h:203
int vect_size(Pvecteur v)
package vecteur - reductions
Definition: reductions.c:47
#define transformer_arguments(x)
Definition: ri.h:2871
#define predicate_system_(x)
Definition: ri.h:2068
Psysteme sc_new(void)
Psysteme sc_new(): alloue un systeme vide, initialise tous les champs avec des valeurs nulles,...
Definition: sc_alloc.c:55
Pbase base
Definition: sc-local.h:75
int dimension
Definition: sc-local.h:74
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
entity entity_to_new_value(entity)
Definition: value.c:859
#define VECTEUR_NUL
DEFINITION DU VECTEUR NUL.

References arguments_add_entity(), Ssysteme::base, CAR, Ssysteme::dimension, ENTITY, entity_to_new_value(), MAPL, predicate_system_, sc_new(), transformer_arguments, transformer_identity(), transformer_relation, vect_add_variable(), vect_size(), and VECTEUR_NUL.

Referenced by add_loop_index_exit_value(), and invariant_wrt_transformer().

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

◆ arguments_to_string()

string arguments_to_string ( string  s,
list  args 
)
Parameters
argsrgs

Definition at line 65 of file prettyprint.c.

66 {
67  pips_internal_error("not implemenented anymore, s=\"%s\", args=%p", s, args);
68  return string_undefined;
69 }
#define string_undefined
Definition: newgen_types.h:40

References pips_internal_error, and string_undefined.

◆ boolean_analyzed_p()

bool boolean_analyzed_p ( void  )

Definition at line 305 of file value.c.

306 {
308 }

References analyze_boolean_scalar_entities.

Referenced by any_expression_to_transformer(), and fortran_data_to_prec_for_variables().

+ Here is the caller graph for this function:

◆ build_transfer_equations()

void build_transfer_equations ( Pcontrainte  leq,
Pcontrainte plteq,
Pbase pb_new 
)

FI: this is the simplest version; It would be possible to build a larger set of transfer equations by adding indirect transfer equations using a new basis till the set is stable, and then by removing equations containing old values which are not defined, again till the result is stable

I guess that these new equations would not change the fix-point and/or the preconditions.

derive the new basis and the old basis

check that the old basis is included in the new basis (else no fix-point!)

Remove equations as long b_old is not included in b_new

could be avoided by using only lteq...

Parameters
leqeq
plteqlteq
pb_newb_new

Definition at line 433 of file fix_point.c.

436 {
438  Pbase b_new = BASE_NULLE;
439  Pbase b_old = BASE_NULLE;
440  Pbase b_diff = BASE_NULLE;
442 
443  ifdebug(8) {
444  pips_debug(8, "begin\ninput equations:\n");
445  egalites_fprint(stderr, leq, (char * (*)(Variable)) external_value_name);
446  }
447 
448  /* FI: this is the simplest version;
449  * It would be possible to build a larger set of transfer equations
450  * by adding indirect transfer equations using a new basis
451  * till the set is stable, and then by removing equations containing
452  * old values which are not defined, again till the result is stable
453  *
454  * I guess that these new equations would not change the fix-point
455  * and/or the preconditions.
456  */
457  for(eq = leq; !CONTRAINTE_UNDEFINED_P(eq); eq = eq->succ) {
460 
461  neq->succ = lteq;
462  lteq = neq;
463  }
464  }
465 
466  ifdebug(8) {
467  pips_debug(8, "preliminary transfer equations:\n");
468  egalites_fprint(stderr, lteq,
469  (char * (*)(Variable)) external_value_name);
470  }
471 
472  /* derive the new basis and the old basis */
473  equations_to_bases(lteq, &b_new, &b_old);
474 
475  /* check that the old basis is included in the new basis (else no
476  fix-point!) */
477  ifdebug(8) {
478  pips_debug(8, "old basis:\n");
479  base_fprint(stderr, b_old, (char * (*)(Variable)) external_value_name);
480  pips_debug(8, "new basis:\n");
481  base_fprint(stderr, b_new, (char * (*)(Variable)) external_value_name);
482  }
483 
484  /* Remove equations as long b_old is not included in b_new */
485  b_diff = base_difference(b_old, b_new);
486  while(!BASE_NULLE_P(b_diff)) {
489 
490  for(eq = lteq; !CONTRAINTE_UNDEFINED_P(eq); eq = next_eq) {
491  bool preserve = true;
493  for(t = contrainte_vecteur(eq);
494  !VECTEUR_UNDEFINED_P(t) && preserve;
495  t = t->succ) {
496  entity e = (entity) vecteur_var(t);
497 
498  preserve = base_contains_variable_p(b_diff, (Variable) e);
499  }
500  next_eq = eq->succ;
501  if(preserve) {
502  eq->succ = n_lteq;
503  n_lteq = eq;
504  }
505  else {
506  contrainte_rm(eq);
507  }
508  }
509  lteq = n_lteq; /* could be avoided by using only lteq... */
510  equations_to_bases(lteq, &b_new, &b_old);
511  b_diff = base_difference(b_old, b_new);
512  }
513 
514  ifdebug(8) {
515  pips_debug(8, "final transfer equations:\n");
516  egalites_fprint(stderr, lteq,
517  (char * (*)(Variable)) external_value_name);
518  pips_debug(8, "old basis:\n");
519  base_fprint(stderr, b_old, (char * (*)(Variable)) external_value_name);
520  pips_debug(8, "new basis:\n");
521  base_fprint(stderr, b_new, (char * (*)(Variable)) external_value_name);
522  }
523 
524  if(!sub_basis_p(b_old, b_new)) {
525  pips_internal_error("Old basis is too large");
526  }
527  base_rm(b_old);
528  b_old = BASE_UNDEFINED;
529  *plteq = lteq;
530  *pb_new = b_new;
531 
532  ifdebug(8) {
533  pips_debug(8, "results\ntransfer equations:\n");
534  egalites_fprint(stderr, lteq, (char * (*)(Variable)) external_value_name);
535  pips_debug(8, "results\ntransfer basis:\n");
536  base_fprint(stderr, b_new, (char * (*)(Variable)) external_value_name);
537  pips_debug(8, "end\n");
538  }
539 }
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
Pbase base_difference(Pbase b1, Pbase b2)
Pbase base_difference(Pbase b1, Pbase b2): allocate b; b = b1 - b2 – with the set meaning return b;.
Definition: base.c:621
bool base_contains_variable_p(Pbase b, Variable v)
bool base_contains_variable_p(Pbase b, Variable v): returns true if variable v is one of b's elements...
Definition: base.c:136
#define CONTRAINTE_UNDEFINED_P(c)
#define contrainte_vecteur(c)
passage au champ vecteur d'une contrainte "a la Newgen"
#define CONTRAINTE_UNDEFINED
#define contrainte_rm(c)
the standard xxx_rm does not return a value
Pcontrainte contrainte_dup(Pcontrainte c_in)
Pcontrainte contrainte_dup(Pcontrainte c_in): allocation d'une contrainte c_out prenant la valeur de ...
Definition: alloc.c:132
void egalites_fprint(FILE *, Pcontrainte, char *(*)(Variable))
bool transfer_equation_p(Pvecteur eq)
A transfer equation is an explicit equation giving one new value as a function of old values and a co...
Definition: fix_point.c:552
void equations_to_bases(Pcontrainte lteq, Pbase *pb_new, Pbase *pb_old)
Definition: fix_point.c:660
bool sub_basis_p(Pbase b1, Pbase b2)
FI: should be moved in base.c.
Definition: fix_point.c:648
void base_fprint(FILE *f, Pbase b, get_variable_name_t variable_name)
void base_fprint(FILE * f, Pbase b, char * (*variable_name)()): impression d'une base sur le fichier ...
Definition: io.c:342
struct Scontrainte * succ
struct Svecteur * succ
Definition: vecteur-local.h:92
const char * external_value_name(entity)
Definition: value.c:753
#define vecteur_var(v)
#define VECTEUR_UNDEFINED
#define base_rm(b)
#define BASE_UNDEFINED
#define BASE_NULLE
MACROS SUR LES BASES.
#define BASE_NULLE_P(b)
#define VECTEUR_UNDEFINED_P(v)

References base_contains_variable_p(), base_difference(), base_fprint(), BASE_NULLE, BASE_NULLE_P, base_rm, BASE_UNDEFINED, contrainte_dup(), contrainte_rm, CONTRAINTE_UNDEFINED, CONTRAINTE_UNDEFINED_P, contrainte_vecteur, egalites_fprint(), eq, equations_to_bases(), external_value_name(), ifdebug, pips_debug, pips_internal_error, sub_basis_p(), Scontrainte::succ, Svecteur::succ, transfer_equation_p(), VECTEUR_UNDEFINED, VECTEUR_UNDEFINED_P, and vecteur_var.

Referenced by transformer_equality_fix_point().

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

◆ check_transformer_list()

bool check_transformer_list ( list  tl)

What do we want to impose?

  1. Only one identity transformer
  2. Common basis?
  3. No empty transformer

The empty transformer list is used to represent the empty transformer...

It must be the first one

Parameters
tll

Definition at line 140 of file transformer_list.c.

141 {
142  bool identity_p = false;
143  // unused: bool one_p = false; // useless for the time being
144 
145  if(ENDP(tl)) {
146  /* The empty transformer list is used to represent the empty
147  transformer... */
148  ;
149  }
150  else {
151  FOREACH(TRANSFORMER, tf, tl) {
152  if(transformer_identity_p(tf)) {
153  if(identity_p) {
154  pips_internal_error("Two identity transformers in one list.");
155  }
156  else {
157  identity_p = true;
158  }
159  }
160  }
161  if(identity_p) {
162  /* It must be the first one */
164  pips_internal_error("The identity transformer is not the list header.");
165  }
166 
167  FOREACH(TRANSFORMER, tf, tl) {
168  if(transformer_empty_p(tf))
169  pips_internal_error("An empty transformer has been found.");
170  }
171  }
172 
173  return true;
174 }
bool transformer_identity_p(transformer t)
Check that t is an identity function.
Definition: basic.c:154

References CAR, ENDP, FOREACH, pips_internal_error, TRANSFORMER, transformer_empty_p(), and transformer_identity_p().

Referenced by apply_transformer_lists_generic(), combine_transformer_lists(), and merge_transformer_lists().

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

◆ clean_up_transformer_list()

list clean_up_transformer_list ( list  tfl)

Eliminate empty transformers and keep at most one identity transformer, placed as first list element.

check_transformer_list(ntfl) should be TRUE.

tfl is fully destroyed (to avoid memory leaks and nightmares); to be more efficient, the transformers moved from the input list into the output list should be detached from the input list and then the input list could be fully destroyed without having to copy any transformers; but FOREACH operates at too high a level for this.

Parameters
tflfl

Definition at line 290 of file transformer_list.c.

291 {
292  list ntfl = NIL;
293  bool identity_p = false;
294 
295  FOREACH(TRANSFORMER, tf, tfl) {
296  bool tf_identity_p = transformer_identity_p(tf);
297  if(!tf_identity_p && !transformer_empty_p(tf))
298  ntfl = CONS(TRANSFORMER, copy_transformer(tf), ntfl);
299  identity_p = identity_p || tf_identity_p;
300  }
301  gen_full_free_list(tfl);
302  ntfl = gen_nreverse(ntfl);
303  if(identity_p)
304  ntfl = CONS(TRANSFORMER, transformer_identity(), ntfl);
305  return ntfl;
306 }
void gen_full_free_list(list l)
Definition: genClib.c:1023

References CONS, copy_transformer(), FOREACH, gen_full_free_list(), gen_nreverse(), NIL, TRANSFORMER, transformer_empty_p(), transformer_identity(), and transformer_identity_p().

Referenced by block_to_transformer_list().

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

◆ combine_transformer_lists()

list combine_transformer_lists ( list  tl1,
list  tl2 
)

each transformer of tl1 must be combined with a transformer of tl2, including the identity transformer.

If an identity transformer is generated and if identity transformers are always first in the list, it will again be first in the returned list.

Parameters
tl1l1
tl2l2

Definition at line 180 of file transformer_list.c.

181 {
182  list ntl = NIL;
183  int n1 = gen_length(tl1);
184  int n2 = gen_length(tl2);
185  int en = 0;
186  int nn = -1;
187 
188  pips_assert("tl1 is OK\n", check_transformer_list(tl1));
189  pips_assert("tl2 is OK\n", check_transformer_list(tl2));
190 
191  FOREACH(TRANSFORMER, t1, tl1) {
192  FOREACH(TRANSFORMER, t2, tl2) {
194 
195  // transformer_empty_p() is not strong enough currently
196  // It does not detect that k<= 2 && k>=3 is empty...
197  nt = transformer_normalize(nt, 2);
198  if(!transformer_empty_p(nt))
199  ntl = CONS(TRANSFORMER, nt, ntl);
200  else
201  en++;
202  }
203  }
204  ntl = gen_nreverse(ntl);
205 
206  nn = gen_length(ntl);
207  pips_assert("ntl is OK\n", check_transformer_list(ntl));
208  pips_assert("nn is n1*n2-en", nn==n1*n2-en);
209 
210  return ntl;
211 }
transformer transformer_normalize(transformer t, int level)
Eliminate (some) rational or integer redundancy.
Definition: transformer.c:932

References check_transformer_list(), CONS, copy_transformer(), FOREACH, gen_length(), gen_nreverse(), NIL, pips_assert, TRANSFORMER, transformer_combine(), transformer_empty_p(), and transformer_normalize().

Referenced by transformer_list_closure_to_precondition_depth_two(), and transformer_list_closure_to_precondition_max_depth().

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

◆ complex_analyzed_p()

bool complex_analyzed_p ( void  )

Definition at line 320 of file value.c.

321 {
323 }

References analyze_complex_scalar_entities.

◆ constant_path_analyzed_p()

◆ constraints_eliminate_constant_terms()

Pcontrainte constraints_eliminate_constant_terms ( Pcontrainte  lc,
Pvecteur  v 
)

cv may now be the null vector

Parameters
lcc

Definition at line 865 of file fix_point.c.

866 {
867  Value c1 = vect_coeff(TCST, v);
869 
870  if(c1==0) {
871  abort();
872  }
873 
874  for(cc = lc; !CONTRAINTE_UNDEFINED_P(cc); cc = contrainte_succ(cc)) {
875  Pvecteur cv = contrainte_vecteur(cc);
876  Value c2;
877 
878  if((c2 = vect_coeff(TCST, cv))!=0) {
879  cv = vect_multiply(cv, c1);
880  cv = vect_cl(cv, -c2, v);
881  }
882 
883  /* cv may now be the null vector */
884  contrainte_vecteur(cc) = cv;
885  }
886 
887  return lc;
888 }
int Value
#define contrainte_succ(c)
#define abort()
Definition: misc-local.h:53
Pvecteur vect_multiply(Pvecteur v, Value x)
Pvecteur vect_multiply(Pvecteur v, Value x): multiplication du vecteur v par le scalaire x,...
Definition: scalaires.c:123
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
Pvecteur vect_cl(Pvecteur v, Value lambda, Pvecteur u)
Definition: binaires.c:181
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 abort, contrainte_succ, CONTRAINTE_UNDEFINED, CONTRAINTE_UNDEFINED_P, contrainte_vecteur, TCST, vect_cl(), vect_coeff(), and vect_multiply().

Referenced by sc_eliminate_constant_terms().

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

◆ constraints_keep_invariants_only()

Pcontrainte constraints_keep_invariants_only ( Pcontrainte  lc)
Parameters
lcc

Definition at line 910 of file fix_point.c.

911 {
912  Pcontrainte cc;
913 
914  for(cc = lc; !CONTRAINTE_UNDEFINED_P(cc); cc = contrainte_succ(cc)) {
915  Pvecteur cv = contrainte_vecteur(cc);
916  if(!invariant_vector_p(cv)) {
917  vect_rm(cv);
919  }
920  }
921 
922  return lc;
923 }
bool invariant_vector_p(Pvecteur v)
A vector (in fact, a constraint) represents an invariant if it is a sum of delta for each variable.
Definition: fix_point.c:934
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78

References contrainte_succ, CONTRAINTE_UNDEFINED_P, contrainte_vecteur, invariant_vector_p(), vect_rm(), and VECTEUR_NUL.

Referenced by sc_keep_invariants_only().

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

◆ dump_transformer()

void dump_transformer ( transformer  tf)
Parameters
tff

Definition at line 134 of file io.c.

136 {
138 }
transformer fprint_transformer(FILE *fd, transformer tf, get_variable_name_t value_name)
Definition: io.c:69
char * dump_value_name(entity e)
char * dump_value_name(e): used as functional argument because entity_name is a macro
Definition: io.c:128
char *(* get_variable_name_t)(Variable)
Definition: vecteur-local.h:62

References dump_value_name(), and fprint_transformer().

+ Here is the call graph for this function:

◆ dump_value_name()

char* dump_value_name ( entity  e)

char * dump_value_name(e): used as functional argument because entity_name is a macro

FI: should be moved in ri-util/entity.c

Definition at line 128 of file io.c.

130 {
131  return entity_name(e);
132 }

References entity_name.

Referenced by check_range_wrt_precondition(), dump_transformer(), fortran_user_call_to_transformer(), print_value_mappings(), transformer_combine(), and translate_global_values().

+ Here is the caller graph for this function:

◆ empty_transformer()

transformer empty_transformer ( transformer  t)

Do not allocate an empty transformer, but transform an allocated transformer into an empty_transformer.

Pretty dangerous because the predicate contained in t may have been deleted before empty_transformer is called. It is not clear that the predicate of t can be freed or not: it is up to the caller to be aware of the problem.

This function is risky to use. It can cause either a memory leak if the predicate is not freed, or a double free if the pointer in the transformer is already dangling. If the predicate has already been freed during some processing at the linear level, the caller must update the pointer transformer_relation(t) with:

transformer_relation(t) = relation_undefined;

before the call.

Definition at line 144 of file basic.c.

145 {
150  return t;
151 }
predicate make_predicate(Psysteme a1)
Definition: ri.c:1820
void free_predicate(predicate p)
Definition: ri.c:1787
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
Psysteme sc_empty(Pbase b)
Psysteme sc_empty(Pbase b): build a Psysteme with one unfeasible constraint to define the empty subsp...
Definition: sc_alloc.c:319

References BASE_NULLE, free_predicate(), gen_free_list(), make_predicate(), NIL, sc_empty(), transformer_arguments, and transformer_relation.

Referenced by modulo_by_a_constant_to_transformer(), statement_to_postcondition(), transformer_combine(), transformer_convex_hulls(), transformer_projection_with_redundancy_elimination_and_check(), and whileloop_to_postcondition().

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

◆ entity_has_values_p()

bool entity_has_values_p ( entity  e)

This function could be made more robust by checking the storage of e.

Formal parameters of analyzed type always have values.

is e a variable whose value(s) (already) are analyzed?

Definition at line 911 of file value.c.

912 {
913  /* is e a variable whose value(s) (already) are analyzed?
914  */
915  pips_assert("value hash table is defined",
917  bool has_values_p = hash_defined_p(hash_entity_to_new_value, (char *) e);
918  return has_values_p;
919 }
bool hash_defined_p(const hash_table htp, const void *key)
true if key has e value in htp.
Definition: hash.c:484

References hash_defined_p(), hash_entity_to_new_value, hash_table_undefined_p, and pips_assert.

Referenced by add_index_range_conditions(), add_inter_or_intraprocedural_field_entities(), add_interprocedural_new_value_entity(), add_interprocedural_value_entities(), add_intraprocedural_value_entities(), add_loop_index_exit_value(), add_or_kill_equivalenced_variables(), any_assign_operation_to_transformer(), any_scalar_assign_to_transformer_list(), any_scalar_assign_to_transformer_without_effect(), apply_abstract_effect_to_transformer(), assign_operation_to_transformer(), assigned_expression_to_transformer(), assigned_expression_to_transformer_list(), c_data_to_prec_for_variables(), declaration_to_transformer(), declaration_to_transformer_list(), dynamic_variables_to_values(), effects_to_arguments(), filter_transformer(), fortran_data_to_prec_for_variables(), fortran_user_call_to_transformer(), generic_apply_effect_to_transformer(), generic_reference_to_transformer(), generic_unary_operation_to_transformer(), integer_assign_to_transformer(), integer_assign_to_transformer_list(), logical_reference_to_transformer(), loop_bound_evaluation_to_transformer(), module_to_value_mappings(), noms_var(), pips_user_value_name(), pointer_unary_operation_to_transformer(), safe_assigned_expression_to_transformer(), safe_assigned_expression_to_transformer_list(), string_expression_to_transformer(), substitute_scalar_stub_in_transformer(), substitute_stubs_in_transformer(), transformer_add_condition_information_updown(), transformer_add_loop_index_incrementation(), transformer_add_loop_index_initialization(), transformer_add_modified_variable_entity(), transformer_add_variable_type_information(), transformer_filter_subsumed_variables(), transformer_general_consistency_p(), transformer_projection_with_redundancy_elimination_and_check(), transformer_variables_filter(), value_mappings_compatible_vector_p(), variable_to_values(), and variables_to_values().

+ Here is the call graph for this function:

◆ entity_to_intermediate_value()

entity entity_to_intermediate_value ( entity  e)

◆ entity_to_new_value()

entity entity_to_new_value ( entity  e)

Definition at line 859 of file value.c.

860 {
861  entity n;
862  if((n = (entity) hash_get(hash_entity_to_new_value, (char *) e))
863  == entity_undefined)
864  pips_internal_error("unbounded entity %s",
865  entity_name(e));
866  return n;
867 }

References entity_name, entity_undefined, hash_entity_to_new_value, hash_get(), and pips_internal_error.

Referenced by add_affine_bound_conditions(), add_loop_index_exit_value(), add_new_alias_value(), add_synonym_values(), affine_to_transformer(), any_assign_operation_to_transformer(), any_scalar_assign_to_transformer_list(), any_scalar_assign_to_transformer_without_effect(), args_to_transformer(), assign_operation_to_transformer(), assigned_expression_to_transformer(), assigned_expression_to_transformer_list(), comp_regions_of_implied_do(), dynamic_variables_to_values(), external_value_name(), filter_transformer(), fortran_user_call_to_transformer(), generic_reference_to_transformer(), logical_reference_to_transformer(), loop_bound_evaluation_to_transformer(), old_value_to_new_value(), remove_entity_values(), string_expression_to_transformer(), substitute_scalar_stub_in_transformer(), substitute_stubs_in_transformer_with_translation_binding(), transformer_add_condition_information_updown(), transformer_add_identity(), transformer_add_loop_index_incrementation(), transformer_add_modified_variable_entity(), transformer_add_value_update(), transformer_add_variable_incrementation(), transformer_add_variable_type_information(), transformer_add_variable_update(), transformer_argument_general_consistency_p(), transformer_arguments_projection(), transformer_convex_hulls(), transformer_derivative_constraints(), transformer_derivative_fix_point(), transformer_domain_intersection(), transformer_internal_consistency_p(), transformer_list_generic_transitive_closure(), transformer_to_domain(), transformer_variables_filter(), update_cp_with_rhs_to_transformer(), value_mappings_compatible_vector_p(), value_passing_summary_transformer(), variable_to_values(), variables_to_new_values(), variables_to_values(), and vect_variables_to_values().

+ Here is the call graph for this function:

◆ entity_to_old_value()

entity entity_to_old_value ( entity  e)

Definition at line 869 of file value.c.

870 {
871  entity o;
872  if((o = (entity) hash_get(hash_entity_to_old_value, (char *) e))
873  == entity_undefined)
874  pips_internal_error("unbounded entity %s",
875  entity_name(e));
876  return o;
877 }

References entity_name, entity_undefined, hash_entity_to_old_value, hash_get(), and pips_internal_error.

Referenced by add_old_alias_value(), add_synonym_values(), add_type_information(), affine_to_transformer(), any_assign_operation_to_transformer(), any_basic_update_operation_to_transformer(), any_scalar_assign_to_transformer_list(), any_scalar_assign_to_transformer_without_effect(), assigned_expression_to_transformer(), assigned_expression_to_transformer_list(), dynamic_variables_to_values(), external_value_name(), fortran_user_call_to_transformer(), new_value_to_old_value(), perform_array_element_substitutions_in_transformer(), precondition_intra_to_inter(), remove_entity_values(), safe_transformer_projection(), statement_to_postcondition(), statement_to_total_precondition(), substitute_scalar_stub_in_transformer(), substitute_stubs_in_transformer_with_translation_binding(), transformer_add_identity(), transformer_add_loop_index_incrementation(), transformer_add_loop_index_initialization(), transformer_add_modified_variable_entity(), transformer_add_value_update(), transformer_add_variable_incrementation(), transformer_add_variable_update(), transformer_arguments_projection(), transformer_combine(), transformer_convex_hulls(), transformer_domain_intersection(), transformer_intersect_range_with_domain(), transformer_list_safe_variables_projection(), transformer_projection_with_redundancy_elimination_and_check(), transformer_range(), transformer_to_domain(), transformer_variables_filter(), update_cp_with_rhs_to_transformer(), value_passing_summary_transformer(), variable_to_values(), variables_to_old_values(), and variables_to_values().

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

◆ equations_to_bases()

void equations_to_bases ( Pcontrainte  lteq,
Pbase pb_new,
Pbase pb_old 
)
Parameters
lteqteq
pb_newb_new
pb_oldb_old

Definition at line 660 of file fix_point.c.

661 {
662  Pbase b_new = BASE_UNDEFINED;
663  Pbase b_old = BASE_UNDEFINED;
665 
666  for(eq = lteq; !CONTRAINTE_UNDEFINED_P(eq); eq = eq->succ) {
667  Pvecteur t;
668 
669  for(t=contrainte_vecteur(eq); !VECTEUR_UNDEFINED_P(t); t = t->succ) {
670  entity e = (entity) vecteur_var(t);
671 
672  if( e != (entity) TCST ) {
673  if(new_value_entity_p(e)) {
674  b_new = vect_add_variable(b_new, (Variable) e);
675  }
676  else {
677  b_old = vect_add_variable(b_old,
679  }
680  }
681  }
682  }
683 
684  *pb_new = b_new;
685  *pb_old = b_old;
686 }
entity old_value_to_new_value(entity)
Definition: value.c:1698
bool new_value_entity_p(entity)
the following three functions are directly or indirectly relative to the current module and its value...
Definition: value.c:925

References BASE_UNDEFINED, CONTRAINTE_UNDEFINED, CONTRAINTE_UNDEFINED_P, contrainte_vecteur, eq, new_value_entity_p(), old_value_to_new_value(), Scontrainte::succ, Svecteur::succ, TCST, vect_add_variable(), VECTEUR_UNDEFINED_P, and vecteur_var.

Referenced by build_transfer_equations().

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

◆ error_free_value_mappings()

void error_free_value_mappings ( void  )

To be called by an error handler.

free previous hash tables, desallocate names; this implies ALL value names were malloced and were not pointer to a ri part

the three tables are assumed to be allocated all together

free names in hash_value_to_name; the other two hash tables contain pointers to the entity tabulated domain and thus need no value freeing

k is discovered unused by lint; it is syntaxically necessary

free the three tables themselves

Definition at line 1222 of file value.c.

1223 {
1224  /* free previous hash tables, desallocate names; this implies ALL
1225  value names were malloced and were not pointer to a ri part */
1226 
1227  /* the three tables are assumed to be allocated all together */
1228 
1229  /* free names in hash_value_to_name; the other two hash tables
1230  contain pointers to the entity tabulated domain and thus need
1231  no value freeing */
1232  /* k is discovered unused by lint; it is syntaxically necessary */
1233  HASH_MAP(k, v, {free(v);}, hash_value_to_name);
1234  // Do not deallocate the names: they are pointers towards parts of
1235  // entity names
1236  //HASH_MAP(k, v, {free(v);}, hash_entity_to_user_value_name);
1237  /* free the three tables themselves */
1245 
1249 }
void free(void *)
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
#define HASH_MAP(k, v, code, ht)
Definition: newgen_hash.h:60
void reset_temporary_value_counter()
Definition: value.c:250
static void reset_value_mappings(void)
Definition: value.c:1188
void reset_analyzed_types()
Definition: value.c:289

References free(), hash_entity_to_intermediate_value, hash_entity_to_new_value, hash_entity_to_old_value, hash_entity_to_user_value_name, HASH_MAP, hash_reference_to_address_of_value, hash_table_free(), hash_type_to_sizeof_value, hash_value_to_name, reset_analyzed_types(), reset_temporary_value_counter(), and reset_value_mappings().

Referenced by free_value_mappings().

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

◆ error_reset_value_mappings()

void error_reset_value_mappings ( void  )

To be called by error handler only.

Potential memory leak.

Definition at line 1205 of file value.c.

1206 {
1208 }

References reset_value_mappings().

Referenced by free_value_mappings(), and module_to_value_mappings().

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

◆ external_entity_to_new_value()

entity external_entity_to_new_value ( entity  e)

there is no decisive test here; a necessary condition is used instead

Definition at line 1411 of file value.c.

1412 {
1413  /* there is no decisive test here; a necessary condition is used instead */
1414 
1415  entity e_new;
1416 
1417  pips_assert("e must be a type analyzable scalar variable", analyzable_scalar_entity_p(e));
1418  e_new = e;
1419  return e_new;
1420 }
bool analyzable_scalar_entity_p(entity e)
The entity type is one of the analyzed types.
Definition: value.c:471

References analyzable_scalar_entity_p(), and pips_assert.

Referenced by add_formal_to_actual_bindings(), formal_and_actual_parameters_association(), fortran_user_call_to_transformer(), generic_reference_to_transformer(), logical_reference_to_transformer(), and substitute_stubs_in_transformer_with_translation_binding().

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

◆ external_entity_to_old_value()

entity external_entity_to_old_value ( entity  e)

find the old value entity if possible or abort I should never have to call this function on an local entity (local entities include static local variables)

Definition at line 1422 of file value.c.

1423 {
1424  /* find the old value entity if possible or abort
1425  I should never have to call this function on an local entity
1426  (local entities include static local variables) */
1427 
1428  entity old_value;
1429  string old_value_name;
1430 
1431  old_value_name = concatenate(entity_name(e),OLD_VALUE_SUFFIX,
1432  (char *) NULL);
1433  old_value = gen_find_tabulated(old_value_name, entity_domain);
1434 
1435  pips_assert("external_entity_to_old_value", old_value!=entity_undefined);
1436 
1437  return old_value;
1438 }

References concatenate(), entity_domain, entity_name, entity_undefined, gen_find_tabulated(), OLD_VALUE_SUFFIX, and pips_assert.

Referenced by fortran_user_call_to_transformer(), perform_array_element_substitutions_in_transformer(), and substitute_stubs_in_transformer_with_translation_binding().

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

◆ external_value_name()

const char* external_value_name ( entity  e)

This should never occur. Please core dump!

Definition at line 753 of file value.c.

754 {
755  const char* s = string_undefined;
756  if(entity_constant_p(e)) {
757  // Used for floating point and string constants? Why entity name?
758  s = entity_local_name(e);
759  }
760  else if(entity_symbolic_p(e)) {
761  // Used for locations, i.e. constant memory access paths
762  s = entity_local_name(e);
763  }
764  else if(null_pointer_value_entity_p(e)) {
765  s = entity_name(e);
766  }
767  else {
768  // it must be one of the values attached to a user variable
770  s = hash_get(hash_value_to_name, (char *) e);
771  // type t = entity_type(e);
772 
774  //&& type_variable_p(t)
775  && !variable_in_module_p(e,m)) {
776  if(global_new_value_p(e)) {
778  s = hash_get(hash_value_to_name, (char *) a);
779  }
780  else if(global_old_value_p(e)) {
782  s = hash_get(hash_value_to_name, (char *) a);
783  }
784  else if(global_intermediate_value_p(e)) {
786  s = hash_get(hash_value_to_name, (char *) a);
787  }
788  else {
789  /* This should never occur. Please core dump! */
790  pips_internal_error("\nUnexpected value \"%s\""
791  " for current module \"%s\"",
792  entity_name(e),
794  }
795  }
796 
797  pips_assert("A value name must be defined",
798  s != HASH_UNDEFINED_VALUE);
799 
800  if(strcmp(module_local_name(m), module_name(s)) == 0
801  ||strcmp(TOP_LEVEL_MODULE_NAME, module_name(s)) == 0) {
802  //s = local_name(s);
804  }
805  }
806 
807  return s;
808 }
bool null_pointer_value_entity_p(entity)
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
bool global_intermediate_value_p(entity e)
Definition: value.c:703
bool global_old_value_p(entity e)
Return true if an entity is a global old value (such as "i#init"...).
Definition: value.c:690
const char * global_value_name_to_user_name(const char *gn)
HASH TABLE USE.
Definition: value.c:741
bool global_new_value_p(entity e)
GLOBAL VALUES.
Definition: value.c:667
#define entity_symbolic_p(e)
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
bool variable_in_module_p(entity, entity)
This test can only be applied to variables, not to functions, subroutines or commons visible from a m...
Definition: variable.c:1610

References entity_constant_p, entity_local_name(), entity_name, entity_symbolic_p, entity_to_intermediate_value(), entity_to_new_value(), entity_to_old_value(), get_current_module_entity(), global_intermediate_value_p(), global_new_value_p(), global_old_value_p(), global_value_name_to_user_name(), hash_get(), HASH_UNDEFINED_VALUE, hash_value_to_name, module_local_name(), module_name(), null_pointer_value_entity_p(), pips_assert, pips_internal_error, string_undefined, TOP_LEVEL_MODULE_NAME, and variable_in_module_p().

Referenced by __attribute__(), add_loop_skip_condition(), build_transfer_equations(), complete_loop_transformer(), complete_loop_transformer_list(), intermediate_value_entity_p(), invariant_vector_p(), loop_to_transformer(), noms_var(), old_complete_whileloop_transformer(), pips_user_value_name(), print_transformer(), print_transformers(), print_value_mappings(), readable_value_name(), recompute_loop_transformer(), remove_entity_values(), standard_whileloop_to_transformer(), transformer_derivative_constraints(), transformer_derivative_fix_point(), transformer_equality_fix_point(), transformer_list_generic_transitive_closure(), transformer_normalize(), and transformer_pattern_fix_point().

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

◆ float_analyzed_p()

bool float_analyzed_p ( void  )

Definition at line 315 of file value.c.

316 {
318 }

References analyze_float_scalar_entities.

Referenced by any_expression_to_transformer(), fortran_data_to_prec_for_variables(), parametric_transformer_empty_p(), and transformer_normalize().

+ Here is the caller graph for this function:

◆ formal_and_actual_parameters_association()

transformer formal_and_actual_parameters_association ( call  c,
transformer  pre 
)

formal_and_actual_parameters_association(call c, transformer pre): Add equalities between actual and formal parameters binding by call c to pre pre := pre U {f = expr } i i for all i such that formal fi is an integer scalar variable and expression expr-i is affine

let's start a long, long, long MAPL, so long that MAPL is a pain

Parameters
prere

Definition at line 2542 of file transformer.c.

2543 {
2544  entity f = call_function(c);
2545  list pc = call_arguments(c);
2547  cons * ce;
2548 
2549  ifdebug(6) {
2550  debug(6,"formal_and_actual_parameters_association",
2551  "begin for call to %s pre=%x\n", module_local_name(f), pre);
2552  dump_transformer(pre);
2553  }
2554 
2555  pips_assert("formal_and_actual_parameters_association",
2556  entity_module_p(f));
2557  pips_assert("formal_and_actual_parameters_association",
2558  pre != transformer_undefined);
2559 
2560  /* let's start a long, long, long MAPL, so long that MAPL is a pain */
2561  for( ce = formals; !ENDP(ce); POP(ce)) {
2562  entity e = ENTITY(CAR(ce));
2564  expression expr;
2565  normalized n;
2566 
2567  if((expr = find_ith_argument(pc, r)) == expression_undefined)
2568  user_error("formal_and_actual_parameters_association",
2569  "not enough args for formal parm. %d\n", r);
2570 
2571  n = NORMALIZE_EXPRESSION(expr);
2572  if(normalized_linear_p(n)) {
2575 
2576  vect_add_elem(&v, (Variable) e_new, -1);
2577  pre = transformer_equality_add(pre, v);
2578  }
2579  }
2580 
2581  free_arguments(formals);
2582 
2583  ifdebug(6) {
2584  debug(6,"formal_and_actual_parameters_association",
2585  "new pre=%x\n", pre);
2586  dump_transformer(pre);
2587  debug(6,"formal_and_actual_parameters_association","end for call to %s\n",
2588  module_local_name(f));
2589  }
2590 
2591  return pre;
2592 }
void free_arguments(cons *args)
Definition: arguments.c:218
transformer transformer_equality_add(transformer tf, Pvecteur i)
Definition: basic.c:383
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define user_error(fn,...)
Definition: misc-local.h:265
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
#define dump_transformer(t)
Definition: print.c:355
#define NORMALIZE_EXPRESSION(e)
bool entity_module_p(entity e)
Definition: entity.c:683
expression find_ith_argument(list args, int n)
Definition: expression.c:1147
#define formal_offset(x)
Definition: ri.h:1408
#define normalized_linear_p(x)
Definition: ri.h:1779
#define call_function(x)
Definition: ri.h:709
#define entity_storage(x)
Definition: ri.h:2794
#define storage_formal(x)
Definition: ri.h:2524
#define expression_undefined
Definition: ri.h:1223
#define call_arguments(x)
Definition: ri.h:711
#define normalized_linear(x)
Definition: ri.h:1781
static list entity_to_formal_integer_parameters(entity f)
get unsorted list of formal integer parameters of module f by declaration filtering; these parameters...
Definition: transformer.c:2517
entity external_entity_to_new_value(entity)
Definition: value.c:1411
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
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

References call_arguments, call_function, CAR, debug(), dump_transformer, ENDP, ENTITY, entity_module_p(), entity_storage, entity_to_formal_integer_parameters(), expression_undefined, external_entity_to_new_value(), f(), find_ith_argument(), formal_offset, free_arguments(), ifdebug, module_local_name(), NORMALIZE_EXPRESSION, normalized_linear, normalized_linear_p, pips_assert, POP, storage_formal, transformer_equality_add(), transformer_undefined, user_error, vect_add_elem(), and vect_dup().

Referenced by interprocedural_abc_arrays(), and translate_to_module_frame().

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

◆ fprint_transformer()

transformer fprint_transformer ( FILE *  fd,
transformer  tf,
get_variable_name_t  value_name 
)

print_transformer returns an int to be compatible with the debug() function; however, debug being a function and not a macro, its arguments are ALWAYS evaluated regardless of the debug level; so a call to print_transformer passed as an argument to debug is ALWAYS effective

print argument list

print relation

Parameters
fdd
tff
value_namealue_name

Definition at line 69 of file io.c.

72 {
73  /* print_transformer returns an int to be compatible with the debug()
74  function; however, debug being a function and not a macro, its
75  arguments are ALWAYS evaluated regardless of the debug level;
76  so a call to print_transformer passed as an argument to debug
77  is ALWAYS effective */
78 
79  if(tf==transformer_undefined)
80  (void) fprintf(stderr,"TRANSFORMER UNDEFINED\n");
81  // For debugging with gdb, dynamic type checking
83  (void) fprintf(stderr,"Arg. \"tf\"is not a transformer.\n");
84  }
85  else {
86  cons * args = transformer_arguments(tf);
88 
89  /* print argument list */
90  (void) fprintf(fd,"arguments:");
91  print_homogeneous_arguments(args, (const char* (*) (entity))value_name);
92 
93  /* print relation */
94  if(SC_UNDEFINED_P(sc))
95  pips_internal_error("undefined relation");
96  (void) fprintf(fd,"\nrelation:");
97  sc_fprint(fd,
98  sc,
99  value_name);
100  }
101 
102  return tf;
103 }
void print_homogeneous_arguments(list args, const char *variable_name(entity))
Functions dealing with entity lists.
Definition: arguments.c:54
#define transformer_domain_number(x)
Definition: ri.h:2869
#define transformer_domain
newgen_test_domain_defined
Definition: ri.h:426
struct Ssysteme * Psysteme
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

References fprintf(), pips_internal_error, predicate_system, print_homogeneous_arguments(), sc_fprint(), transformer_arguments, transformer_domain, transformer_domain_number, transformer_relation, and transformer_undefined.

Referenced by complete_loop_transformer(), complete_loop_transformer_list(), dump_transformer(), expression_equal_in_context_p(), expression_less_than_in_context(), fprint_transformers(), loop_to_transformer(), old_complete_whileloop_transformer(), print_any_transformer(), print_transformer(), standard_whileloop_to_transformer(), transformer_derivative_fix_point(), transformer_equality_fix_point(), transformer_filter(), transformer_list_generic_transitive_closure(), transformer_normalize(), transformer_pattern_fix_point(), and transformer_projection_with_redundancy_elimination_and_check().

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

◆ fprint_transformers()

list fprint_transformers ( FILE *  fd,
list  tl,
get_variable_name_t  value_name 
)
Parameters
fdd
tll
value_namealue_name

Definition at line 105 of file io.c.

108 {
109  if(ENDP(tl)) {
110  // FI: I changed my mind; this is a way to represent a non
111  //feasible transformer
112  //pips_internal_error("transformer lists should never be empty.");
113  fprintf(fd, "Empty transformer list\n");
114  }
115  else {
116  FOREACH(TRANSFORMER, tf, tl) {
117  fprint_transformer(fd, tf, value_name);
118  }
119  }
120  return tl;
121 }

References ENDP, FOREACH, fprint_transformer(), fprintf(), and TRANSFORMER.

Referenced by print_transformers().

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

◆ free_transformers()

void free_transformers ( transformer  t,
  ... 
)

Analyze in args the variadic arguments that may be after t:

Since a variadic function in C must have at least 1 non variadic argument (here the s), just skew the varargs analysis:

Get the next argument:

Release the variadic analyzis:

Definition at line 73 of file basic.c.

73  {
74  va_list args;
75 
76  /* Analyze in args the variadic arguments that may be after t: */
77  va_start(args, t);
78  /* Since a variadic function in C must have at least 1 non variadic
79  argument (here the s), just skew the varargs analysis: */
80  do {
82  /* Get the next argument: */
83  t = va_arg(args, transformer);
84  } while(t!=NULL);
85  /* Release the variadic analyzis: */
86  va_end(args);
87 }

References free_transformer().

Referenced by loop_to_enter_transformer().

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

◆ free_value_mappings()

void free_value_mappings ( void  )

Normal call to free the mappings.

Definition at line 1212 of file value.c.

1213 {
1215  pips_assert("no free of undefined mappings",
1218 }
void reset_hooks_unregister(reset_func_t)
remove registered cleanup hook.
Definition: reset_hooks.c:73
void error_free_value_mappings(void)
To be called by an error handler.
Definition: value.c:1222
void error_reset_value_mappings(void)
To be called by error handler only.
Definition: value.c:1205

References error_free_value_mappings(), error_reset_value_mappings(), hash_entity_to_old_value, hash_table_undefined_p, pips_assert, and reset_hooks_unregister().

Referenced by add_alias_pairs_for_this_caller(), alias_classes(), alias_lists(), alias_pairs(), aliases_text(), any_complexities(), array_expansion(), bdsc_code_instrumentation(), call_site_to_module_precondition_text(), continuation_conditions(), dsc_code_parallelization(), generic_module_name_to_transformers(), generic_print_xml_application(), get_continuation_condition_text(), get_semantic_text(), hbdsc_parallelization(), initial_precondition(), isolate_statement(), kernel_data_mapping(), kernel_load_store_engine(), module_name_to_preconditions(), module_name_to_total_preconditions(), out_regions_from_caller_to_callee(), partial_eval(), phrase_comEngine_distributor(), phrase_distributor(), phrase_distributor_control_code(), pragma_outliner(), print_initial_precondition(), print_program_precondition(), program_precondition(), reset_convex_in_out_regions(), reset_convex_rw_regions(), reset_convex_summary_in_out_regions(), reset_convex_summary_rw_regions(), safescale_distributor(), safescale_module_analysis(), sequence_dependence_graph(), solve_hardware_constraints(), spire_distributed_unstructured_to_structured(), summary_precondition(), summary_total_postcondition(), and update_precondition_with_call_site_preconditions().

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

◆ generic_equality_to_transformer()

transformer generic_equality_to_transformer ( entity  e,
entity  f,
bool  assignment,
bool  unary_minus_p 
)
Parameters
assignmentssignment
unary_minus_pnary_minus_p

Definition at line 72 of file transformer.c.

76 {
79  cons * tf_args = NIL;
80  Pcontrainte c;
81 
82  ifdebug(9) {
83  pips_debug(9, "entity e: %s, entity f: %s, %s\n",
85  assignment? "Is an assignment" : "Is not an assignment");
86  }
87 
88  if(assignment)
89  tf_args = CONS(ENTITY, e, NIL);
90 
91  vect_add_elem(&eq, (Variable) f, unary_minus_p? VALUE_ONE : VALUE_MONE);
92  c = contrainte_make(eq);
93  tf = make_transformer(tf_args,
95 
96  ifdebug(9) {
97  pips_debug(9, "end with tf=%p\n", tf);
98  dump_transformer(tf);
99  }
100 
101  return tf;
102 }
transformer make_transformer(list a1, predicate a2)
Definition: ri.c:2649
#define VALUE_MONE
#define VALUE_ONE
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_make(Pcontrainte leg, Pcontrainte lineg)
Psysteme sc_make(Pcontrainte leg, Pcontrainte lineg): allocation et initialisation d'un systeme d'equ...
Definition: sc.c:78
Pvecteur vect_new(Variable var, Value coeff)
Pvecteur vect_new(Variable var,Value coeff): allocation d'un vecteur colineaire au vecteur de base va...
Definition: alloc.c:110

References CONS, contrainte_make(), CONTRAINTE_UNDEFINED, dump_transformer, ENTITY, entity_local_name(), eq, f(), ifdebug, make_predicate(), make_transformer(), NIL, pips_debug, sc_make(), transformer_undefined, VALUE_MONE, VALUE_ONE, vect_add_elem(), and vect_new().

Referenced by simple_equality_to_transformer(), and simple_unary_minus_to_transformer().

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

◆ generic_transformer_list_to_transformer()

transformer generic_transformer_list_to_transformer ( list  ltl,
bool  active_p 
)

Reduce the transformer list with the convex hull operator.

If active_p is true, skip transformers that do not update the state. Beyond the identity transformer, any transformer without arguments does not really update the state, although it may restrict it.

A new transformer is always allocated. The transformers in the transformer list ltl are freed.

Look for the first useful transformer in the list

Only range conditions have been found: the store is restricted but not changed.

Take care of the following useful transformers

Look for the next useful transformer in the list

Parameters
ltltl
active_pctive_p

Definition at line 384 of file transformer_list.c.

385 {
386  transformer ltf = transformer_undefined; // list transformer
387 
388  if(ENDP(ltl))
389  ltf = transformer_empty();
390  else {
391  list ctl = ltl;
392  /* Look for the first useful transformer in the list */
393  FOREACH(TRANSFORMER, tf, ltl) {
394  if(!active_p || !ENDP(transformer_arguments(tf))) {
395  ltf = copy_transformer(tf);
396  free_transformer(tf);
397  POP(ctl);
398  break;
399  }
400  POP(ctl);
401  }
402  if(ENDP(ctl)) {
403  if(transformer_undefined_p(ltf))
404  /* Only range conditions have been found: the store is
405  restricted but not changed. */
406  ltf = transformer_identity();
407  }
408  else {
409  /* Take care of the following useful transformers */
410  while(!ENDP(ctl)) {
411  /* Look for the next useful transformer in the list */
412  FOREACH(TRANSFORMER, tf, ctl) {
413  if(!active_p || !ENDP(transformer_arguments(tf))) {
414  transformer ntf = copy_transformer(tf);
415  transformer ptf = ltf;
416  ltf = transformer_convex_hull(ptf, ntf);
417  free_transformer(ntf);
418  free_transformer(ptf);
419  POP(ctl);
420  break;
421  }
422  POP(ctl);
423  }
424  }
425  }
426  }
427 
428  return ltf;
429 }
transformer transformer_empty()
Allocate an empty transformer.
Definition: basic.c:120
#define transformer_undefined_p(x)
Definition: ri.h:2848

References copy_transformer(), ENDP, FOREACH, free_transformer(), POP, TRANSFORMER, transformer_arguments, transformer_convex_hull(), transformer_empty(), transformer_identity(), transformer_undefined, and transformer_undefined_p.

Referenced by active_transformer_list_to_transformer(), and transformer_list_to_transformer().

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

◆ generic_value_name()

const char* generic_value_name ( entity  e)

else if (entity_has_values_p(e)){

n = external_value_name(e);

Definition at line 81 of file prettyprint.c.

82 {
83  const char* n = string_undefined;
84 
85  if(e == (entity) TCST) {
86  n = "";
87  }
88  else {
89  (void) gen_check((gen_chunk *) e, entity_domain);
91  n = entity_minimal_name(e);
92  }
93  /* else if (entity_has_values_p(e)){ */
95  && value_entity_p(e)){
96  /* n = external_value_name(e); */
97  n = pips_user_value_name(e);
98  }
99  else {
100  n = entity_minimal_name(e);
101  }
102  }
103  return n;
104 }
gen_chunk * gen_check(gen_chunk *obj, int t)
GEN_CHECK checks that the gen_chunk received OBJ is of the appropriate TYPE.
Definition: genClib.c:2356
const char * entity_minimal_name(entity e)
Do preserve scope informations.
Definition: naming.c:214
bool value_entity_p(entity)
Definition: value.c:976
const char * pips_user_value_name(entity)
This function is called many times when the constraints and the system of constraints are sorted usin...
Definition: value.c:815
bool local_temporary_value_entity_p(entity)
Definition: value.c:654
bool hash_value_to_name_undefined_p(void)
Definition: value.c:1199
A gen_chunk is used to store every object.
Definition: genC.h:58

References entity_domain, entity_minimal_name(), gen_check(), hash_value_to_name_undefined_p(), local_temporary_value_entity_p(), pips_user_value_name(), string_undefined, TCST, and value_entity_p().

Referenced by varval_value_name_is_inferior_p().

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

◆ global_intermediate_value_p()

bool global_intermediate_value_p ( entity  e)

this is not a general test; it will only work for GLOBAL values

Definition at line 703 of file value.c.

704 {
705  /* this is not a general test; it will only work for GLOBAL values */
706  string suf = strchr(entity_local_name(e), SEMANTICS_SEPARATOR);
707  bool intermediate = false;
708 
709  if(suf!=NULL)
710  intermediate = strcmp(entity_module_name(e), SEMANTICS_MODULE_NAME) != 0 &&
711  strcmp(suf, INTERMEDIATE_VALUE_SUFFIX) == 0;
712 
713  return intermediate;
714 }
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
#define SEMANTICS_SEPARATOR
Must be used in suffixes and prefixes below.
#define SEMANTICS_MODULE_NAME
include file for transformer library

References entity_local_name(), entity_module_name(), INTERMEDIATE_VALUE_SUFFIX, SEMANTICS_MODULE_NAME, and SEMANTICS_SEPARATOR.

Referenced by external_value_name().

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

◆ global_new_value_p()

bool global_new_value_p ( entity  e)

GLOBAL VALUES.

this is not a general test; it will only work for GLOBAL values

this function should always return false because new value = variable (FI)

=> suf == NULL string suf = strchr(entity_local_name(e), SEMANTICS_SEPARATOR);

pips_assert("global_new_value", suf != NULL);

new = strcmp(entity_module_name(e), SEMANTICS_MODULE_NAME) != 0 && strcmp(suf, NEW_VALUE_SUFFIX) == 0;

Definition at line 667 of file value.c.

668 {
669  bool new = false;
670  /* this is not a general test; it will only work for GLOBAL values */
671 
672  /* this function should always return false because new value = variable (FI) */
673 
674  /* => suf == NULL
675  string suf = strchr(entity_local_name(e), SEMANTICS_SEPARATOR);
676 
677  pips_assert("global_new_value", suf != NULL);
678 
679  new = strcmp(entity_module_name(e), SEMANTICS_MODULE_NAME) != 0 &&
680  strcmp(suf, NEW_VALUE_SUFFIX) == 0;
681  */
682 
683  pips_assert("global_new_value", new == false && e==e);
684 
685  return new;
686 }

References pips_assert.

Referenced by external_value_name().

+ Here is the caller graph for this function:

◆ global_new_value_to_global_old_value()

entity global_new_value_to_global_old_value ( entity  v_new)

There is no real test for global new values

Parameters
v_new_new

Definition at line 716 of file value.c.

717 {
718  entity v_old = entity_undefined;
719 
720  /* There is no real test for global new values */
721 
722  pips_assert("new value must be a real variable entity, denoting the new value",
723  strcmp(entity_module_name(v_new), SEMANTICS_MODULE_NAME) != 0);
724 
725  string v_old_name = concatenate(entity_name(v_new), OLD_VALUE_SUFFIX, NULL);
726  v_old = (entity) gen_find_tabulated(v_old_name, entity_domain);
727  if(v_old==NULL) v_old = entity_undefined;
728 
729  return v_old;
730 }

References concatenate(), entity_domain, entity_module_name(), entity_name, entity_undefined, gen_find_tabulated(), OLD_VALUE_SUFFIX, pips_assert, and SEMANTICS_MODULE_NAME.

Referenced by c_user_function_call_to_transformer(), fortran_user_function_call_to_transformer(), substitute_scalar_stub_in_transformer(), transformer_projection_with_redundancy_elimination_and_check(), and translate_global_value().

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

◆ global_old_value_p()

bool global_old_value_p ( entity  e)

Return true if an entity is a global old value (such as "i#init"...).

this is not a general test; it will only work for GLOBAL values

Definition at line 690 of file value.c.

691 {
692  /* this is not a general test; it will only work for GLOBAL values */
693  string suf = strchr(entity_local_name(e), SEMANTICS_SEPARATOR);
694  bool old = false;
695 
696  if(suf!=NULL)
697  old = strcmp(entity_module_name(e), SEMANTICS_MODULE_NAME) != 0 &&
698  strcmp(suf, OLD_VALUE_SUFFIX) == 0;
699 
700  return old;
701 }

References entity_local_name(), entity_module_name(), OLD_VALUE_SUFFIX, SEMANTICS_MODULE_NAME, and SEMANTICS_SEPARATOR.

Referenced by external_value_name(), and translate_global_value().

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

◆ global_value_name_to_user_name()

const char* global_value_name_to_user_name ( const char *  gn)

HASH TABLE USE.

Return a variable value name or map a variable to its different variable values. the '#' character used in value naming conflicts with the reserved character for struct naming

Parameters
gnn

Definition at line 741 of file value.c.

742 {
743  const char* un = strrchr(gn, BLOCK_SEP_CHAR);
744 
745  if(un==NULL)
746  un = local_name(gn);
747  else
748  un++;
749 
750  return un;
751 }
const char * local_name(const char *s)
Does not take care of block scopes and returns a pointer.
Definition: entity_names.c:221
#define BLOCK_SEP_CHAR
Definition: naming-local.h:51

References BLOCK_SEP_CHAR, and local_name().

Referenced by external_value_name().

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

◆ hash_entity_to_values_undefined_p()

bool hash_entity_to_values_undefined_p ( void  )

value.c

Definition at line 229 of file value.c.

230 {
232 }

References hash_entity_to_new_value, and hash_table_undefined_p.

◆ hash_value_to_name_undefined_p()

bool hash_value_to_name_undefined_p ( void  )

Definition at line 1199 of file value.c.

1200 {
1202 }

References hash_table_undefined_p, and hash_value_to_name.

Referenced by generic_value_name().

+ Here is the caller graph for this function:

◆ integer_analyzed_p()

bool integer_analyzed_p ( void  )

Definition at line 300 of file value.c.

301 {
303 }

References analyze_integer_scalar_entities.

Referenced by any_expression_to_transformer().

+ Here is the caller graph for this function:

◆ intermediate_value_entity_p()

bool intermediate_value_entity_p ( entity  e)

Definition at line 955 of file value.c.

956 {
957  string s = strstr(external_value_name(e), INTERMEDIATE_VALUE_SUFFIX);
958 
959  return s!=NULL;
960 }
const char * external_value_name(entity e)
Definition: value.c:753

References external_value_name(), and INTERMEDIATE_VALUE_SUFFIX.

Referenced by transformer_internal_consistency_p(), and value_to_variable().

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

◆ invariant_vector_p()

bool invariant_vector_p ( Pvecteur  v)

A vector (in fact, a constraint) represents an invariant if it is a sum of delta for each variable.

Let di = i::new - i::old. If v = sigma (di) = 0, v can be used to build a loop invariant.

It is assumed that constant terms have been substituted earlier using a loop counter.

OK, you could argue for invariant = false, but this would not help my debugging!

if v_sum is non zero, you might try to bound it wrt the loop precondition?

Definition at line 934 of file fix_point.c.

935 {
936  bool invariant = true;
938  Pvecteur v_old = VECTEUR_NUL;
939  Pvecteur v_new = VECTEUR_NUL;
940  Pvecteur v_sum = VECTEUR_UNDEFINED;
941 
942  ifdebug(8) {
943  pips_debug(8, "begin for vector: ");
944  vect_fprint(stderr, v, (char * (*)(Variable)) external_value_name);
945  }
946 
947  for(cv=v; !VECTEUR_UNDEFINED_P(cv); cv = vecteur_succ(cv)) {
948  if(vecteur_var(cv)==TCST) {
949  /* OK, you could argue for invariant = false,
950  * but this would not help my debugging!
951  */
952  pips_internal_error("Constant term in a potential invariant vector!");
953  }
954  else {
955  entity e = (entity) vecteur_var(cv);
956  entity var = value_to_variable(e);
957 
958 
959  if(old_value_entity_p(e)) {
960  vect_add_elem(&v_old, (Variable) var, vecteur_val(cv));
961  }
962  else if(new_value_entity_p(e)) {
963  vect_add_elem(&v_new, (Variable) var, vecteur_val(cv));
964  }
965  else {
966  pips_internal_error("Non value entity %s in invariant vector",
967  entity_name(e));
968  }
969  }
970  }
971 
972  v_sum = vect_add(v_new, v_old);
973 
974  ifdebug(8) {
975  pips_debug(8, "vector v_new: ");
976  vect_fprint(stderr, v_new, (char * (*)(Variable)) external_value_name);
977  pips_debug(8, "vector v_old: ");
978  vect_fprint(stderr, v_old, (char * (*)(Variable)) external_value_name);
979  pips_debug(8, "vector v_sum: ");
980  vect_fprint(stderr, v_sum, (char * (*)(Variable)) external_value_name);
981  }
982 
983  if(VECTEUR_NUL_P(v_sum)) {
984  invariant = true;
985  }
986  else {
987  /* if v_sum is non zero, you might try to bound it
988  * wrt the loop precondition?
989  */
990  invariant = false;
991  vect_rm(v_sum);
992  }
993 
994  vect_rm(v_new);
995  vect_rm(v_old);
996 
997  pips_debug(8, "end invariant=%s\n",
998  bool_to_string(invariant));
999 
1000  return invariant;
1001 }
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
string bool_to_string(bool)
Definition: string.c:243
bool old_value_entity_p(entity)
Definition: value.c:936
entity value_to_variable(entity)
Get the primitive variable associated to any value involved in a transformer.
Definition: value.c:1624
#define vecteur_val(v)
#define vecteur_succ(v)
#define VECTEUR_NUL_P(v)
Pvecteur vect_add(Pvecteur v1, Pvecteur v2)
package vecteur - operations binaires
Definition: binaires.c:53

References bool_to_string(), entity_name, external_value_name(), ifdebug, new_value_entity_p(), old_value_entity_p(), pips_debug, pips_internal_error, TCST, value_to_variable(), vect_add(), vect_add_elem(), vect_fprint(), vect_rm(), VECTEUR_NUL, VECTEUR_NUL_P, vecteur_succ, VECTEUR_UNDEFINED, VECTEUR_UNDEFINED_P, vecteur_val, and vecteur_var.

Referenced by constraints_keep_invariants_only().

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

◆ invariant_wrt_transformer()

transformer invariant_wrt_transformer ( transformer  p,
transformer  tf 
)

transformer invariant_wrt_transformer(transformer p, transformer tf): Assume that tf is a fix-point operator.

Old version: keep the invariant part of predicat p wrt tf in a VERY crude way; old and new values related to an entity modified by tf are discarded by projection, regardless of the way they are modified; information that they are modified is preserved; in fact, this is not a projection but a cylinder based on the projection. inf A real fix-point a la Halbwachs should be used p' = UNION(tf^k(p)) k=0 or simply one of PIPS loop fix-points.

Be careful if tf is not feasible because the result is p itself which may not be what you expect.

p is not modified.

if it is expensive, maybe it should not be computed over and over...

tf? fptf?

must be freed, otherwise it is leaked.

Parameters
tff

Definition at line 1948 of file transformer.c.

1949 {
1952 
1953  if(!transformer_undefined_p(p)) {
1954  //transformer raw_inv = transformer_undefined;
1955  if(false)
1956  {
1958  }
1959  else
1960  {
1961  /* if it is expensive, maybe it should not be computed over and over...
1962  */
1964  }
1965 
1966  inv = transformer_apply(fptf, p); /* tf? fptf? */
1967  //inv = transformer_range(raw_inv);
1968 
1969  //free_transformer(raw_inv); // Newgen syntax
1970  transformer_free(fptf); /* must be freed, otherwise it is leaked. */
1971  }
1972  else {
1973  inv = transformer_undefined;
1974  }
1975  return inv;
1976 }
void transformer_free(transformer t)
Definition: basic.c:68
transformer transformer_derivative_fix_point(transformer)
Computation of a transitive closure using constraints on the discrete derivative.
Definition: fix_point.c:1067
transformer args_to_transformer(list le)
Generates a transformer abstracting a totally unknown modification of the values associated to variab...
Definition: transformer.c:1907

References args_to_transformer(), transformer_apply(), transformer_arguments, transformer_derivative_fix_point(), transformer_free(), transformer_undefined, and transformer_undefined_p.

Referenced by loop_to_transformer(), new_loop_to_transformer(), old_complete_whileloop_transformer(), process_ready_node(), standard_whileloop_to_transformer(), unstructured_to_postcondition(), and unstructured_to_total_precondition().

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

◆ local_intermediate_value_entity_p()

bool local_intermediate_value_entity_p ( entity  e)

this is not a general test; it will only work for LOCAL values

Definition at line 648 of file value.c.

649 {
650  /* this is not a general test; it will only work for LOCAL values */
651  return strncmp(entity_local_name(e), INTERMEDIATE_VALUE_PREFIX, 2) == 0;
652 }
#define INTERMEDIATE_VALUE_PREFIX

References entity_local_name(), and INTERMEDIATE_VALUE_PREFIX.

+ Here is the call graph for this function:

◆ local_old_value_entity_p()

bool local_old_value_entity_p ( entity  e)

Return true if an entity is a local old value (such as "o#0" for a global value "i#init"...).

This is not a general test; it will only work for LOCAL values

Definition at line 642 of file value.c.

643 {
644  /* This is not a general test; it will only work for LOCAL values */
645  return strncmp(entity_local_name(e), OLD_VALUE_PREFIX, 2) == 0;
646 }
#define OLD_VALUE_PREFIX
internal entity names (FI: I should have used suffixes to be consistent with external suffixes

References entity_local_name(), and OLD_VALUE_PREFIX.

Referenced by add_type_information(), and regions_transformer_apply().

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

◆ local_temporary_value_entity_p()

bool local_temporary_value_entity_p ( entity  e)

this is not a general test; it will only work for LOCAL values

Definition at line 654 of file value.c.

655 {
656  /* this is not a general test; it will only work for LOCAL values */
657  return strncmp(entity_local_name(e), TEMPORARY_VALUE_PREFIX, 2) == 0;
658 }
#define TEMPORARY_VALUE_PREFIX

References entity_local_name(), and TEMPORARY_VALUE_PREFIX.

Referenced by generic_transformer_to_analyzed_locations(), generic_value_name(), non_local_temporary_value_entity_p(), old_value_entity_p(), readable_value_name(), transformer_add_sign_information(), transformer_projection_with_redundancy_elimination_and_check(), transformer_temporary_value_projection(), transformer_to_potential_stub_translation(), transformer_with_temporary_values_p(), and value_mappings_compatible_vector_p().

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

◆ look_for_the_best_counter()

Pvecteur look_for_the_best_counter ( Pcontrainte  egs)

Try to identify a loop counter among the equation egs.

If the transformer has been build naively, a loop counter should have a transformer equation like i::new = i::old + K_i where K_i is a numerical constant.

Since the loop counter is later used to eliminate constant terms in other constraints, variable i with the minimal absolute value K_i shuold be chosen.

Parameters
egsgs

Definition at line 797 of file fix_point.c.

798 {
799  Pvecteur v_inc = VECTEUR_UNDEFINED;
801  int inc = 0;
802 
803  for(leq = egs;
805  leq = contrainte_succ(leq)) {
806 
807  Pvecteur v = contrainte_vecteur(leq);
808  int c_inc = 0;
809 
810  if(vect_size(v)==3) {
811  entity p_old_index = entity_undefined;
812  entity p_new_index = entity_undefined;
814  bool failed = false;
815  for(lv = v; !VECTEUR_UNDEFINED_P(lv) && !failed; lv = vecteur_succ(lv)) {
816  if(vecteur_var(lv) == TCST) {
817  c_inc = (int) vecteur_val(lv);
818  }
819  else if(old_value_entity_p((entity) vecteur_var(lv))) {
820  if(entity_undefined_p(p_old_index))
821  p_old_index = (entity) vecteur_var(lv);
822  else
823  failed = true;
824  }
825  else if(new_value_entity_p((entity) vecteur_var(lv))) {
826  if(entity_undefined_p(p_new_index))
827  p_new_index = (entity) vecteur_var(lv);
828  else
829  failed = true;
830  }
831  else {
832  pips_internal_error("Unexpected value entity %s",
834  }
835  }
836  if(!failed && value_to_variable(p_old_index) == value_to_variable(p_new_index)) {
837  if(ABS(c_inc) < ABS(inc) || c_inc == 1) {
838  inc = c_inc;
839  v_inc = v;
840  }
841  }
842  }
843  }
844 
845  return v_inc;
846 }
void const char const char const int
#define ABS(x)
was: #define value_mult(v,w) value_direct_multiply(v,w) #define value_product(v,w) value_direct_produ...
#define entity_undefined_p(x)
Definition: ri.h:2762

References ABS, contrainte_succ, CONTRAINTE_UNDEFINED, CONTRAINTE_UNDEFINED_P, contrainte_vecteur, entity_local_name(), entity_undefined, entity_undefined_p, int, new_value_entity_p(), old_value_entity_p(), pips_internal_error, TCST, value_to_variable(), vect_size(), vecteur_succ, VECTEUR_UNDEFINED, VECTEUR_UNDEFINED_P, vecteur_val, and vecteur_var.

Referenced by transformer_pattern_fix_point().

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

◆ make_local_temporary_integer_value_entity()

entity make_local_temporary_integer_value_entity ( void  )

Definition at line 629 of file value.c.

630 {
631  basic b = make_basic(is_basic_int, (void *) 4);
634 
635  free_type(t);
636  return tmp;
637 }
basic make_basic(enum basic_utype tag, void *val)
Definition: ri.c:155
variable make_variable(basic a1, list a2, list a3)
Definition: ri.c:2895
void free_type(type p)
Definition: ri.c:2658
type make_type(enum type_utype tag, void *val)
Definition: ri.c:2706
static entity make_local_value_entity(int n, int nature, type t)
LOCAL VALUE ENTITY.
Definition: value.c:547
static int local_temporary_value_counter
Definition: value.c:242
@ is_basic_int
Definition: ri.h:571
@ is_type_variable
Definition: ri.h:2900

References free_type(), is_basic_int, is_type_variable, local_temporary_value_counter, make_basic(), make_local_value_entity(), make_type(), make_variable(), and NIL.

Referenced by add_type_information(), bitwise_xor_to_transformer(), logical_not_to_transformer(), modulo_to_transformer(), transformer_add_condition_information_updown(), transformer_derivative_fix_point(), and transformer_list_generic_transitive_closure().

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

◆ make_local_temporary_value_entity()

entity make_local_temporary_value_entity ( type  t)

FI: is it easier to admit value of type void than to make a special case? Let see if it works... No, it's not a good idea because value are assumed of type variable in many places.

Definition at line 605 of file value.c.

606 {
608 
609  /* FI: is it easier to admit value of type void than to make a
610  special case? Let see if it works... No, it's not a good idea
611  because value are assumed of type variable in many places. */
612  if(analyzed_type_p(t))
614  else
615  pips_internal_error("Request for a temporary value with a non analyzed type.\n");
616 
617  return tv;
618 }

References analyzed_type_p(), entity_undefined, local_temporary_value_counter, make_local_value_entity(), and pips_internal_error.

Referenced by add_formal_to_actual_bindings(), add_index_bound_conditions(), add_type_information(), addition_operation_to_transformer(), any_assign_operation_to_transformer(), any_scalar_assign_to_transformer_list(), any_scalar_assign_to_transformer_without_effect(), assigned_expression_to_transformer(), assigned_expression_to_transformer_list(), call_to_transformer(), expression_multiply_sizeof_to_transformer(), expression_to_transformer(), generic_abs_to_transformer(), generic_minmax_to_transformer(), iabs_to_transformer(), integer_binary_operation_to_transformer(), integer_expression_and_precondition_to_integer_interval(), integer_left_shift_to_transformer(), integer_minmax_to_transformer(), integer_multiply_to_transformer(), logical_binary_operation_to_transformer(), logical_unary_operation_to_transformer(), loop_bound_evaluation_to_transformer(), loop_to_enter_transformer(), unary_minus_operation_to_transformer(), update_cp_with_rhs_to_transformer(), update_operation_to_transformer(), and value_passing_summary_transformer().

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

◆ make_local_temporary_value_entity_with_basic()

entity make_local_temporary_value_entity_with_basic ( basic  b)

Definition at line 620 of file value.c.

621 {
624 
625  free_type(t);
626  return tmp;
627 }
basic copy_basic(basic p)
BASIC.
Definition: ri.c:104

References copy_basic(), free_type(), is_type_variable, local_temporary_value_counter, make_local_value_entity(), make_type(), make_variable(), and NIL.

Referenced by condition_to_transformer(), precondition_minmax_of_expression(), and transformer_add_any_relation_information().

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

◆ merge_transformer_lists()

list merge_transformer_lists ( list  tl1,
list  tl2 
)

transformer_list.c

transformer_list.c

Tansformer lists are used to delay convex hulls and to refine the precondition computation of loops by putting aside the identity transformer.

If there is an identity transformer in the list, it is supposed to be the first one in the list.

However, some control paths are almost identity transformers because the store is apparently unchanged. However, they contain predicates on the possible values. Although they have no arguments, and hence, the store is left unchanged, they are different from the identity transformer bebcause the relation is smaller.

So it should be up to the function using the transformer list to decide how to cope with transformers that restrict the identity transition. Must not be used, beware of library cycles: include "semantics.h" Union of two lists

If the list includes the identity transformer, it must be the first in the list and be nowehere else

It is not clear if transformer lists will be stored in hash tables... Hence I do not know if the input list should be freed, reused or left unshared. To be conservative, no alias is created.

Do we have to worry about different bases in transformers?

Too much information is sometimes lost with this simplification

Parameters
tl1l1
tl2l2

Definition at line 74 of file transformer_list.c.

75 {
76  list ntl = NIL;
77  list ntl1 = NIL;
78  list ntl2 = NIL;
79 
80  if(ENDP(tl1))
81  ntl = gen_full_copy_list(tl2);
82  else if(ENDP(tl2))
83  ntl = gen_full_copy_list(tl1);
84  else {
85  /* Do we have to worry about different bases in transformers? */
86  transformer t1 = TRANSFORMER(CAR(tl1));
87  transformer t2 = TRANSFORMER(CAR(tl2));
88 
89  /* Too much information is sometimes lost with this
90  simplification */
91  /*
92  if(ENDP(transformer_arguments(t1))) {
93  free_transformer(t1);
94  t1 = transformer_identity();
95  }
96 
97  if(ENDP(transformer_arguments(t2))) {
98  free_transformer(t2);
99  t2 = transformer_identity();
100  }
101  */
102 
105  }
106  if(transformer_identity_p(t1))
107  ntl1 = gen_full_copy_list(CDR(tl1));
108  else
109  ntl1 = gen_full_copy_list(tl1);
110  if(transformer_identity_p(t2))
111  ntl2 = gen_full_copy_list(CDR(tl2));
112  else
113  ntl2 = gen_full_copy_list(tl2);
114  ntl1 = gen_nconc(ntl1, ntl2);
115  ntl = gen_nconc(ntl, ntl1);
116  }
117 
118  ifdebug(1) {
119  int ntll = gen_length(ntl);
120  int tl1l = gen_length(tl1);
121  int tl2l = gen_length(tl2);
122  pips_assert("The new list is about the sum of the input lists.\n",
123  ntll>=tl1l+tl2l-1 && ntll<=tl1l+tl2l);
124  pips_assert("The new transformer list is legal",
126  }
127  return ntl;
128 }
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
list gen_full_copy_list(list l)
Copy a list structure with element copy.
Definition: list.c:535

References CAR, CDR, check_transformer_list(), CONS, ENDP, gen_full_copy_list(), gen_length(), gen_nconc(), ifdebug, NIL, pips_assert, TRANSFORMER, transformer_identity(), and transformer_identity_p().

Referenced by test_to_transformer_list().

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

◆ modified_variables_with_values()

list modified_variables_with_values ( void  )

Return the list of all analyzed variables which are modified in the current module.

If they are modified, they must have old values.

The intermediate values could be used as well

Definition at line 1094 of file value.c.

1095 {
1096  /* The intermediate values could be used as well */
1097  /*
1098  list ivl = mapping_to_domain_list(hash_entity_to_old_value); // initial
1099  // value list
1100  list wvl = NIL; // written variable list
1101 
1102  FOREACH(ENTITY, e, ivl) {
1103  entity wv = new_value_to_variable(e);
1104  ivl = CONS(ENTITY, wv, ivl);
1105  }
1106 
1107  gen_reverse(wvl);
1108  */
1110  return wvl;
1111 }
static list mapping_to_domain_list(hash_table h)
Returns the list of entities in the mapping domain.
Definition: value.c:1048

References hash_entity_to_old_value, and mapping_to_domain_list().

Referenced by apply_abstract_effect_to_transformer(), generic_reference_to_transformer(), and transformer_combine().

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

◆ move_transformer()

transformer move_transformer ( transformer  t1,
transformer  t2 
)

Move arguments and predicate of t2 into t1, free old arguments and predicate of t1, free what's left of t2.

This is used to perform a side effect on an argument when a function allocates a new transformer to return a result. t2 should not be used after a call to move_transformer()

Parameters
t11
t22

Definition at line 939 of file basic.c.

940 {
941  pips_assert("t1 is consistent on entry", transformer_consistency_p(t1));
942  pips_assert("t2 is consistent on entry", transformer_consistency_p(t2));
943 
947 
951  predicate_system(transformer_relation(t2))= SC_UNDEFINED;
952 
953  free_transformer(t2);
954 
955  pips_assert("t1 is consistent on exit", transformer_consistency_p(t1));
956 
957  return t1;
958 }
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
void sc_rm(Psysteme ps)
void sc_rm(Psysteme ps): liberation de l'espace memoire occupe par le systeme de contraintes ps;
Definition: sc_alloc.c:277

References free_arguments(), free_transformer(), NIL, pips_assert, predicate_system, sc_rm(), transformer_arguments, transformer_consistency_p(), and transformer_relation.

Referenced by transformer_domain_intersection().

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

◆ new_value_entity_p()

bool new_value_entity_p ( entity  e)

the following three functions are directly or indirectly relative to the current module and its value hash tables.

since new values are always variable entities, hash_entity_to_new_value can be used for this test

Definition at line 925 of file value.c.

926 {
927  /* since new values are always variable entities, hash_entity_to_new_value
928  can be used for this test */
929 
930  pips_assert("new_value_entity_p",e != entity_undefined);
931 
932  return (entity) hash_get(hash_entity_to_new_value, (char *) e)
933  == e;
934 }

References entity_undefined, hash_entity_to_new_value, hash_get(), and pips_assert.

Referenced by build_transfer_matrix(), equations_to_bases(), invariant_vector_p(), look_for_the_best_counter(), new_value_in_transfer_equation(), transfer_equation_p(), transformer_internal_consistency_p(), and value_to_variable().

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

◆ new_value_in_transfer_equation()

entity new_value_in_transfer_equation ( Pvecteur  eq)

for gcc

Parameters
eqq

Definition at line 570 of file fix_point.c.

571 {
572  Pvecteur t;
573  int n_new = 0;
574  Value coeff = VALUE_ZERO; /* for gcc */
575  entity new_value = entity_undefined;
576 
577  for(t=eq; !VECTEUR_UNDEFINED_P(t) && n_new <= 1; t = t->succ) {
578  entity e = (entity) vecteur_var(t);
579 
580  if( e != (entity) TCST && new_value_entity_p(e) &&
582  new_value = e;
583  coeff = vecteur_val(t);
584  n_new++;
585  }
586  }
587 
588  if(value_mone_p(coeff)) {
589  for(t=eq; !VECTEUR_UNDEFINED_P(t) && n_new <= 1; t = t->succ) {
591  }
592  }
593 
594  pips_assert("n_new==1", n_new==1);
595 
596  return new_value;
597 }
#define VALUE_ZERO
#define value_mone_p(val)
#define value_oppose(ref)
#define value_one_p(val)

References entity_undefined, eq, new_value_entity_p(), pips_assert, Svecteur::succ, TCST, value_mone_p, value_one_p, value_oppose, VALUE_ZERO, VECTEUR_UNDEFINED_P, vecteur_val, and vecteur_var.

Referenced by build_transfer_matrix().

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

◆ new_value_to_old_value()

entity new_value_to_old_value ( entity  n_val)

FI: correct code entity var = entity_undefined;

var = value_to_variable(n_val); o_val = entity_to_old_value(var);

FI: faster code

Parameters
n_val_val

Definition at line 1710 of file value.c.

1711 {
1712  entity o_val = entity_undefined;
1713 
1714  /* FI: correct code
1715  entity var = entity_undefined;
1716 
1717  var = value_to_variable(n_val);
1718  o_val = entity_to_old_value(var);
1719  */
1720 
1721  /* FI: faster code */
1722  o_val = entity_to_old_value(n_val);
1723 
1724  return o_val;
1725 }

References entity_to_old_value(), and entity_undefined.

Referenced by transformer_equality_fix_point(), and upwards_vect_rename().

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

◆ no_elim()

Psysteme no_elim ( Psysteme  ps)
Parameters
pss

Definition at line 1306 of file transformer.c.

1307 {
1308  return ps;
1309 }

◆ number_of_analyzed_values()

int number_of_analyzed_values ( void  )

Definition at line 1148 of file value.c.

1149 {
1151 }

References hash_table_entry_count(), and hash_value_to_name.

Referenced by module_to_value_mappings().

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

◆ number_of_analyzed_variables()

int number_of_analyzed_variables ( void  )

FI: looks more like the number of values used.

Definition at line 1160 of file value.c.

1161 {
1163 }

References hash_table_entry_count(), and hash_value_to_name.

+ Here is the call graph for this function:

◆ number_of_temporary_values()

int number_of_temporary_values ( void  )

Definition at line 255 of file value.c.

256 {
258 }

References local_temporary_value_counter.

Referenced by transformer_temporary_value_projection(), and transformer_with_temporary_values_p().

+ Here is the caller graph for this function:

◆ old_transformer_free()

void old_transformer_free ( transformer  t)

I should use gen_free directly but Psysteme is not yet properly interfaced with NewGen

gen_free should stop before trying to free a Psysteme and won't free entities in arguments because they are tabulated

commented out for DRET demo

end of DRET demo

Definition at line 89 of file basic.c.

90 {
91  /* I should use gen_free directly but Psysteme is not yet properly
92  interfaced with NewGen */
93  Psysteme s;
94 
95  pips_assert("transformer_free", t != transformer_undefined);
96 
98  sc_rm(s);
99  predicate_system_(transformer_relation(t)) = SC_UNDEFINED;
100  /* gen_free should stop before trying to free a Psysteme and
101  won't free entities in arguments because they are tabulated */
102  /* commented out for DRET demo */
103  /*
104  gen_free(t);
105  */
106  /* end of DRET demo */
107 }

References pips_assert, predicate_system, predicate_system_, sc_rm(), transformer_relation, and transformer_undefined.

+ Here is the call graph for this function:

◆ old_value_entity_p()

bool old_value_entity_p ( entity  e)

Temporary values do not have an external name.

OLD_VALUE_PREFIX is not used for global old values

string s = strstr(external_value_name(e), OLD_VALUE_SUFFIX);

string s = strstr(entity_local_name(e), OLD_VALUE_PREFIX);

Definition at line 936 of file value.c.

937 {
938  /* Temporary values do not have an external name. */
939  /* OLD_VALUE_PREFIX is not used for global old values */
940  /* string s = strstr(external_value_name(e), OLD_VALUE_SUFFIX); */
941  /* string s = strstr(entity_local_name(e), OLD_VALUE_PREFIX); */
942 
944  string s1 = strstr(entity_local_name(e), OLD_VALUE_SUFFIX);
945  // Need to remake the search for OLD_VALUE_PREFIX
946  // bug for toto#...
947  string s2 = strstr(entity_local_name(e), OLD_VALUE_PREFIX);
948  // s2==entity_local_name(e) : for the case toto#...
949  return s1!=NULL || (s2!=NULL && s2==entity_local_name(e));
950  }
951  else
952  return false;
953 }
bool local_temporary_value_entity_p(entity e)
Definition: value.c:654
s1
Definition: set.c:247

References entity_local_name(), local_temporary_value_entity_p(), OLD_VALUE_PREFIX, OLD_VALUE_SUFFIX, and s1.

Referenced by expression_less_than_in_context(), invariant_vector_p(), look_for_the_best_counter(), my_system_remove_variables(), precondition_filter_old_values(), print_call_precondition(), remove_temporal_variables_from_system(), transformer_derivative_constraints(), transformer_derivative_fix_point(), transformer_general_consistency_p(), transformer_internal_consistency_p(), transformer_list_generic_transitive_closure(), and value_to_variable().

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

◆ old_value_to_new_value()

entity old_value_to_new_value ( entity  o_val)

o_val = variable_to_old_value(var);

Parameters
o_val_val

Definition at line 1698 of file value.c.

1699 {
1700  entity var = entity_undefined;
1701  entity n_val = entity_undefined;
1702 
1703  var = value_to_variable(o_val);
1704  /* o_val = variable_to_old_value(var); */
1705  n_val = entity_to_new_value(var);
1706 
1707  return n_val;
1708 }

References entity_to_new_value(), entity_undefined, and value_to_variable().

Referenced by build_transfer_matrix(), and equations_to_bases().

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

◆ one_to_one_transformers_combine()

list one_to_one_transformers_combine ( list  tl1,
list  tl2 
)

Combine each transformer of transformer list tl1 with the corresponding transformer in transformer list tl2.

Side-effect on tl1. See comments for transformer_combine().

See combine_transformer_lists() to combine each element of t1 with each element of t2.

Parameters
tl1l1
tl2l2

Definition at line 476 of file transformer.c.

477 {
478  list ntl2 = tl2;
479  pips_assert("The two lists have the same number of elements",
480  gen_length(tl1)==gen_length(tl2));
481  FOREACH(TRANSFORMER, t1, tl1) {
482  transformer t2 = TRANSFORMER(CAR(ntl2));
483  t1 = transformer_combine(t1, t2);
484  POP(ntl2);
485  }
486  return tl1;
487 }

References CAR, FOREACH, gen_length(), pips_assert, POP, TRANSFORMER, and transformer_combine().

Referenced by transformer_list_closure_to_precondition_depth_two(), and transformer_list_closure_to_precondition_max_depth().

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

◆ pips_user_value_name()

const char* pips_user_value_name ( entity  e)

This function is called many times when the constraints and the system of constraints are sorted using lexicographic information based on this particular value name.

See for instance Semantics-New/freia_52.c. Hence it is memorized.

Definition at line 815 of file value.c.

816 {
817  pips_debug(9, "start with entity : %s\n", entity_name(e));
818  const char* uvn = string_undefined;
819 
820  if(e == (entity) TCST) {
821  uvn = "";
822  }
823  else {
824  // To check the execution speed, uncomment the next line
825  // return entity_name(e);
826  uvn = hash_get(hash_entity_to_user_value_name, (char *) e);
827 
828  if(uvn==HASH_UNDEFINED_VALUE) {
829  // Need to discriminate the case of an address_of value
830  // because the hash table are reset between each pass
831  if (address_of_value_entity_p(e)) {
832  entity v = value_to_variable(e);
833  string temp = strdup(entity_name(e));
834  string indice = strstr(temp, "[");
835  if (indice != NULL)
836  *(indice+strlen(indice)-strlen(ADDRESS_OF_SUFFIX)) = '\0';
837  uvn = strdup(concatenate("&", entity_user_name(v), indice, (char *) NULL));
838  free(temp);
839  }
840  else if (null_pointer_value_entity_p(e)) {
841  uvn = strdup("NULL");
842  }
843  else if (sizeof_value_entity_p(e)) {
844  type t = entity_type(e);
845  uvn = strdup(concatenate("sizeof(", type_to_full_string_definition(t), ")", (char *) NULL));
846  }
847  else {
848  (void) gen_check((gen_chunk *) e, entity_domain);
851  }
852  hash_put(hash_entity_to_user_value_name, (char *) e, uvn);
853  }
854  }
855  pips_debug(9, "end with string : %s\n", uvn);
856  return uvn;
857 }
char * string
STRING.
Definition: newgen_types.h:39
bool entity_has_values_p(entity e)
This function could be made more robust by checking the storage of e.
Definition: value.c:911
bool address_of_value_entity_p(entity e)
Definition: value.c:962
bool sizeof_value_entity_p(entity e)
Definition: value.c:969

References ADDRESS_OF_SUFFIX, address_of_value_entity_p(), concatenate(), entity_domain, entity_has_values_p(), entity_minimal_name(), entity_name, entity_type, entity_user_name(), external_value_name(), free(), gen_check(), hash_entity_to_user_value_name, hash_get(), hash_put(), HASH_UNDEFINED_VALUE, null_pointer_value_entity_p(), pips_debug, sizeof_value_entity_p(), strdup(), string_undefined, TCST, type_to_full_string_definition(), and value_to_variable().

Referenced by generic_value_name(), is_inferior_pvarval(), semantics_is_inferior_pvarval(), text_continuation(), and text_transformer().

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

◆ pointer_analyzed_p()

bool pointer_analyzed_p ( void  )

Definition at line 325 of file value.c.

326 {
328 }

References analyze_pointer_scalar_entities.

Referenced by any_expression_to_transformer().

+ Here is the caller graph for this function:

◆ precondition_to_abstract_store()

transformer precondition_to_abstract_store ( transformer  pre)

Get rid of all old values and arguments.

Argument pre is unchanged and result as is allocated. Should be a call to transformer_range(). Should not be in basic.c.

Project all old values

Redefine the arguments

Parameters
prere

Definition at line 871 of file basic.c.

872 {
873  transformer as = transformer_dup(pre);
874 
875  /* Project all old values */
877 
878  /* Redefine the arguments */
881 
882  return as;
883 }
transformer transformer_projection(transformer t, list args)
values in args must be in t's base
Definition: transformer.c:1267

References gen_free_list(), NIL, transformer_arguments, transformer_dup(), and transformer_projection().

Referenced by test_to_transformer(), and test_to_transformer_list().

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

◆ precondition_to_string()

string precondition_to_string ( transformer  pre)
Parameters
prere

Definition at line 58 of file prettyprint.c.

60 {
61  pips_internal_error("not implemenented anymore, pre=%p", pre);
62  return string_undefined;
63 }

References pips_internal_error, and string_undefined.

Referenced by comp_regions_of_implied_do(), and evaluate_var_to_complexity().

+ Here is the caller graph for this function:

◆ print_any_transformer()

transformer print_any_transformer ( transformer  tf)

For debugging without problem from temporary values.

Parameters
tff

Definition at line 56 of file io.c.

57 {
58  return fprint_transformer(stderr, tf,
60 }

References entity_local_name(), and fprint_transformer().

+ Here is the call graph for this function:

◆ print_transformer()

transformer print_transformer ( transformer  tf)

io.c

io.c

Francois Irigoin, 21 April 1990 print_transformer(tf): not a macro because of dbx and gdb

Parameters
tff

Definition at line 48 of file io.c.

49 {
50  (void) fprint_transformer(stderr, tf,
52  return tf;
53 }

References external_value_name(), and fprint_transformer().

+ Here is the call graph for this function:

◆ print_transformers()

list print_transformers ( list  tl)

◆ print_value_mappings()

void print_value_mappings ( void  )

Definition at line 993 of file value.c.

994 {
995  (void) fprintf(stderr,"\nhash table value to name:\n");
998 
999  (void) fprintf(stderr,"\nhash table entity to new value:\n");
1000  /*
1001  hash_table_fprintf(stderr, entity_local_name, external_value_name,
1002  hash_entity_to_new_value);
1003  */
1006 
1007  (void) fprintf(stderr,"\nhash table entity to old value:\n");
1010 
1011  (void) fprintf(stderr, "\nhash table entity to intermediate value:\n");
1014 
1015  (void) fprintf(stderr, "\nhash table reference to address_of value:\n");
1018 
1019  (void) fprintf(stderr, "\nhash table entity to sizeof value:\n");
1022 }
void hash_table_fprintf(FILE *f, gen_string_func_t key_to_string, gen_string_func_t value_to_string, const hash_table htp)
This function prints the content of the hash_table pointed to by htp on file descriptor f,...
Definition: hash.c:548
string(* gen_string_func_t)(const void *)
Definition: newgen_types.h:111
static string string_identity(string s)
used with hash_table_fprintf
Definition: value.c:990

References dump_value_name(), entity_minimal_name(), external_value_name(), fprintf(), hash_entity_to_intermediate_value, hash_entity_to_new_value, hash_entity_to_old_value, hash_reference_to_address_of_value, hash_table_fprintf(), hash_type_to_sizeof_value, hash_value_to_name, reference_to_string(), string_identity(), and type_to_full_string_definition().

Referenced by module_to_value_mappings().

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

◆ readable_value_name()

const char* readable_value_name ( entity  v)

For debugging purposes, we might have to print system with temporary values.

Definition at line 1769 of file value.c.

1770 {
1771  const char* n ;
1772 
1774  n = entity_local_name(v);
1775  }
1776  else {
1777  n = external_value_name(v);
1778  }
1779 
1780  return n;
1781 }

References entity_local_name(), external_value_name(), and local_temporary_value_entity_p().

Referenced by generic_module_name_to_transformers(), module_name_to_preconditions(), and module_name_to_total_preconditions().

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

◆ reference_to_address_entity()

entity reference_to_address_entity ( reference  r)

The address is the address of a variable or of a reference such as &a[5], not a of a value.

The reference must be a constant memory access path. It does not have to be atomic, as struct are not considered atomic, following Pierre Jouvelot's view point since partial updates are possible.

An address is a constant within a C user function.

As a constant, it must be encoded as a 0-ary function, just like 1.0 or true.

We use the user representation as entity name, namey &a[5].

We do not use array names as constant pointers because they alreay are entities with types and storage. So the address of array a is &a[0].

References can be points-to references, i.e. fields can be encoded as indices.

trict_constant_path_p(r)

Should this local constant be added to the module declarations ?

Definition at line 1285 of file value.c.

1286 {
1288  // if(can_be_constant_path_p(r) /*strict_constant_path_p(r)*/) {
1289  /*strict_constant_path_p(r)*/
1291  entity v = reference_variable(r);
1292  /* Should this local constant be added to the module declarations ? */
1293  string mn = (string) entity_module_name(v);
1294  string ln = strdup(concatenate("&", reference_to_string(r), NULL));
1297  a = FindOrCreateEntity(mn, ln);
1298  entity_type(a) = ft;
1305  }
1306  return a;
1307 }
functional make_functional(list a1, type a2)
Definition: ri.c:1109
storage make_storage_rom(void)
Definition: ri.c:2285
type make_type_functional(functional _field_)
Definition: ri.c:2718
symbolic make_symbolic(expression a1, constant a2)
Definition: ri.c:2369
reference copy_reference(reference p)
REFERENCE.
Definition: ri.c:2047
constant make_constant_unknown(void)
Definition: ri.c:424
value make_value_symbolic(symbolic _field_)
Definition: ri.c:2838
#define unary_intrinsic_expression(name, e)
Building quickly bool expressions, FC.
#define ADDRESS_OF_OPERATOR_NAME
@ DEFAULT_ENTITY_KIND
entity FindOrCreateEntity(const char *package, const char *local_name)
Problem: A functional global entity may be referenced without parenthesis or CALL keyword in a functi...
Definition: entity.c:1586
expression reference_to_expression(reference r)
Definition: expression.c:196
#define entity_kind(x)
Definition: ri.h:2798
#define entity_initial(x)
Definition: ri.h:2796

References ADDRESS_OF_OPERATOR_NAME, concatenate(), copy_reference(), copy_type(), DEFAULT_ENTITY_KIND, entity_initial, entity_kind, entity_module_name(), entity_storage, entity_type, entity_undefined, FindOrCreateEntity(), make_constant_unknown(), make_functional(), make_storage_rom(), make_symbolic(), make_type_functional(), make_value_symbolic(), NIL, points_to_reference_to_concrete_type(), reference_to_expression(), reference_to_string(), reference_variable, store_independent_points_to_reference_p(), strdup(), and unary_intrinsic_expression.

+ Here is the call graph for this function:

◆ reference_to_address_of_value()

entity reference_to_address_of_value ( reference  r)

Definition at line 889 of file value.c.

890 {
891  entity n;
892  if((n = (entity) hash_get(hash_reference_to_address_of_value, (char *) r))
893  == entity_undefined)
894  pips_internal_error("unbounded reference %s",
896  return n;
897 }

References entity_undefined, hash_get(), hash_reference_to_address_of_value, pips_internal_error, and reference_to_string().

+ Here is the call graph for this function:

◆ relation_to_string()

string relation_to_string ( string  ,
Psysteme  ,
char *  *)(entity 
)

◆ relation_to_transformer()

transformer relation_to_transformer ( entity  op,
entity  e1,
entity  e2,
bool  veracity 
)

e and f are assumed to be values.

Operator op is overloaded and the result is operator and type dependent

Beware of type coercion... Fabien conjectures that values with incompatible types won't get mixed up...

type independent

Non convex information

Parameters
opp
e11
e22
veracityeracity

Definition at line 139 of file transformer.c.

141 {
146  Pvecteur ineq = VECTEUR_NUL;
149 
150  ifdebug(9) {
151  pips_debug(9, "Begin for entity e1: %s of basic %s, "
152  "entity e2: %s of basic %s and operator %s\n",
155  module_local_name(op));
156  }
157 
158  /* Beware of type coercion... Fabien conjectures that values with
159  incompatible types won't get mixed up... */
160 
161  if((ENTITY_EQUAL_P(op) && veracity)
162  || (ENTITY_NON_EQUAL_P(op) && !veracity)) {
163  /* type independent */
164  eq = vect_new((Variable) e1, VALUE_ONE);
166  }
167  else if((ENTITY_NON_EQUAL_P(op) && veracity)
168  || (ENTITY_EQUAL_P(op) && !veracity)) {
169  /* Non convex information */
170  ;
171  }
172  else if((ENTITY_LESS_OR_EQUAL_P(op) && veracity)
173  || (ENTITY_GREATER_THAN_P(op) && !veracity)) {
174  ineq = vect_new((Variable) e1, VALUE_ONE);
175  vect_add_elem(&ineq, (Variable) e2, VALUE_MONE);
176  }
177  else if((ENTITY_LESS_THAN_P(op) && veracity)
178  ||(ENTITY_GREATER_OR_EQUAL_P(op) && !veracity)) {
179  ineq = vect_new((Variable) e1, VALUE_ONE);
180  vect_add_elem(&ineq, (Variable) e2, VALUE_MONE);
181  // if we want to authorize to compare a pointer with an integer
182  //if((basic_int_p(b1) || basic_logical_p(b1) || basic_pointer_p(b1))
183  // && (basic_int_p(b2) || basic_logical_p(b2) || basic_pointer_p(b2))) {
184  // if we only want to compare a pointer with an another pointer
185  if(((basic_int_p(b1) || basic_logical_p(b1))
186  && (basic_int_p(b2) || basic_logical_p(b2)))
187  || (basic_pointer_p(b1) && basic_pointer_p(b2))) {
188  vect_add_elem(&ineq, TCST, VALUE_ONE);
189  }
190  }
191  else if((ENTITY_GREATER_OR_EQUAL_P(op) && veracity)
192  || (ENTITY_LESS_THAN_P(op) && !veracity)) {
193  ineq = vect_new((Variable) e1, VALUE_MONE);
194  vect_add_elem(&ineq, (Variable) e2, VALUE_ONE);
195  }
196  else if((ENTITY_GREATER_THAN_P(op) && veracity)
197  || (ENTITY_LESS_OR_EQUAL_P(op) && !veracity)) {
198  ineq = vect_new((Variable) e1, VALUE_MONE);
199  vect_add_elem(&ineq, (Variable) e2, VALUE_ONE);
200  // if we want to authorize to compare a pointer with an integer
201  //if((basic_int_p(b1) || basic_logical_p(b1) || basic_pointer_p(b1))
202  // && (basic_int_p(b2) || basic_logical_p(b2) || basic_pointer_p(b2))) {
203  // if we only want to compare a pointer with an another pointer
204  if(((basic_int_p(b1) || basic_logical_p(b1))
205  && (basic_int_p(b2) || basic_logical_p(b2)))
206  || (basic_pointer_p(b1) && basic_pointer_p(b2))) {
207  vect_add_elem(&ineq, TCST, VALUE_ONE);
208  }
209  }
210  else {
211  pips_internal_error("Unexpected relational operator %s", entity_name(op));
212  }
213 
215  cineq = VECTEUR_NUL_P(ineq)? CONTRAINTE_UNDEFINED : contrainte_make(ineq);
216 
217  if(ceq!=CONTRAINTE_UNDEFINED||cineq!=CONTRAINTE_UNDEFINED) {
218  tf = make_transformer(NIL,
219  make_predicate(sc_make(ceq, cineq)));
220  }
221 
222  ifdebug(9) {
223  pips_debug(9, "end with tf=%p\n", tf);
224  dump_transformer(tf);
225  }
226 
227  return tf;
228 }
string basic_to_string(basic)
Definition: type.c:87
#define ENTITY_NON_EQUAL_P(e)
#define ENTITY_EQUAL_P(e)
#define ENTITY_LESS_THAN_P(e)
#define ENTITY_GREATER_THAN_P(e)
#define ENTITY_LESS_OR_EQUAL_P(e)
#define ENTITY_GREATER_OR_EQUAL_P(e)
Value b2
Definition: sc_gram.c:105
Value b1
booleen indiquant quel membre est en cours d'analyse
Definition: sc_gram.c:105

References b1, b2, basic_int_p, basic_logical_p, basic_pointer_p, basic_to_string(), contrainte_make(), CONTRAINTE_UNDEFINED, dump_transformer, ENTITY_EQUAL_P, ENTITY_GREATER_OR_EQUAL_P, ENTITY_GREATER_THAN_P, ENTITY_LESS_OR_EQUAL_P, ENTITY_LESS_THAN_P, entity_local_name(), entity_name, ENTITY_NON_EQUAL_P, entity_type, eq, ifdebug, make_predicate(), make_transformer(), module_local_name(), NIL, pips_debug, pips_internal_error, sc_make(), TCST, transformer_undefined, type_variable, VALUE_MONE, VALUE_ONE, variable_basic, vect_add_elem(), vect_new(), VECTEUR_NUL, and VECTEUR_NUL_P.

Referenced by transformer_add_any_relation_information().

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

◆ remove_entity_values()

void remove_entity_values ( entity  e,
bool  readonly 
)

pips_assert("remove_entity_values", e != entity_undefined);

Parameters
readonlyeadonly

Definition at line 1545 of file value.c.

1546 {
1547  entity new_value = entity_to_new_value(e);
1548  const char* s;
1549 
1550  /* pips_assert("remove_entity_values", e != entity_undefined); */
1551  pips_assert("remove_entity_values", new_value != entity_undefined);
1552 
1553  s = external_value_name(new_value);
1554  pips_assert("remove_entity_values", s != (char *) NULL);
1555  (void) hash_del(hash_value_to_name, (char *) new_value);
1556  (void) hash_del(hash_entity_to_new_value, (char *) e);
1557 
1558  if(!readonly) {
1559  entity old_value = entity_to_old_value(e);
1560  entity intermediate_value = entity_to_intermediate_value(e);
1561 
1562  pips_assert("remove_entity_values", old_value != entity_undefined);
1563  pips_assert("remove_entity_values",
1564  intermediate_value!=entity_undefined);
1565 
1566  s = external_value_name(old_value);
1567  pips_assert("remove_entity_values", s != (char *) NULL);
1568  (void) hash_del(hash_value_to_name, (char *) old_value);
1569  s = external_value_name(intermediate_value);
1570  pips_assert("remove_entity_values", s != (char *) NULL);
1571  (void) hash_del(hash_value_to_name, (char *) intermediate_value);
1572 
1573  (void) hash_del(hash_entity_to_old_value, (char *) e);
1574  (void) hash_del(hash_entity_to_intermediate_value, (char *) e);
1575  }
1576 }
void * hash_del(hash_table htp, const void *key)
this function removes from the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:439

References entity_to_intermediate_value(), entity_to_new_value(), entity_to_old_value(), entity_undefined, external_value_name(), hash_del(), hash_entity_to_intermediate_value, hash_entity_to_new_value, hash_entity_to_old_value, hash_value_to_name, and pips_assert.

Referenced by add_or_kill_equivalenced_variables().

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

◆ reset_analyzed_types()

◆ reset_temporary_value_counter()

◆ reset_value_counters()

void reset_value_counters ( void  )

Definition at line 244 of file value.c.

245 {
248 }
static int local_old_value_counter
Definition: value.c:241
static int local_intermediate_value_counter
Two counters used to assign meaningless value entities to local variables.
Definition: value.c:240

References local_intermediate_value_counter, and local_old_value_counter.

Referenced by module_to_value_mappings().

+ Here is the caller graph for this function:

◆ safe_transformer_projection()

transformer safe_transformer_projection ( transformer  t,
list  args 
)

t may be undefined, args may contain values unrelated to t

keep only values of args related to the transformer t

Make sure v is in the basis

Make sure the old value is projected too

Parameters
argsrgs

Definition at line 1187 of file transformer.c.

1188 {
1190  if(!transformer_undefined_p(t)) {
1192  list nargs = NIL;
1193 
1194  /* keep only values of args related to the transformer t */
1195  FOREACH(ENTITY, v, args) {
1196  /* Make sure v is in the basis */
1197  if(base_contains_variable_p(sc_base(r), (Variable) v)) {
1198  nargs = arguments_add_entity(nargs, v);
1199  }
1201  /* Make sure the old value is projected too */
1202  entity ov = entity_to_old_value(v);
1203  if(base_contains_variable_p(sc_base(r), (Variable) ov)) {
1204  nargs = arguments_add_entity(nargs, ov);
1205  }
1206  }
1207  }
1208 
1209  nt = transformer_projection(t, nargs);
1210  gen_free_list(nargs);
1211  }
1212  return nt;
1213 }
bool entity_is_argument_p(entity e, cons *args)
Definition: arguments.c:150
entity entity_to_old_value(entity)
Definition: value.c:869

References arguments_add_entity(), base_contains_variable_p(), ENTITY, entity_is_argument_p(), entity_to_old_value(), FOREACH, gen_free_list(), NIL, predicate_system, transformer_arguments, transformer_projection(), transformer_relation, transformer_undefined, and transformer_undefined_p.

Referenced by add_index_bound_conditions(), add_type_information(), loop_to_transformer(), statement_to_postcondition(), statement_to_transformer(), statement_to_transformer_list(), substitute_stubs_in_transformer(), transformer_list_multiple_closure_to_precondition(), and transformer_list_safe_variables_projection().

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

◆ same_dimension_p()

bool same_dimension_p ( entity  actual_array,
entity  dummy_array,
list  l_actual_ref,
size_t  i,
transformer  context 
)

This function returns true if the actual array and the dummy array have the same dimension number i, with respect to the current context (precondition + association) In case if the actual argument is an array element, we have to add the following condition: the i-th subscript of the array element is equal to its correspond lower bound.

The following test is necessary in case of array reshaping

Parameters
actual_arrayctual_array
dummy_arrayummy_array
l_actual_ref_actual_ref
contextontext

Definition at line 2665 of file transformer.c.

2668 {
2669  variable actual_var = type_variable(entity_type(actual_array));
2670  variable dummy_var = type_variable(entity_type(dummy_array));
2671  list l_actual_dims = variable_dimensions(actual_var);
2672  list l_dummy_dims = variable_dimensions(dummy_var);
2673 
2674  /* The following test is necessary in case of array reshaping */
2675  if ((i <= gen_length(l_actual_dims)) && (i < gen_length(l_dummy_dims)))
2676  {
2677  dimension dummy_dim = find_ith_dimension(l_dummy_dims,i);
2678  expression dummy_lower = dimension_lower(dummy_dim);
2679  expression dummy_upper = dimension_upper(dummy_dim);
2680  dimension actual_dim = find_ith_dimension(l_actual_dims,i);
2681  expression actual_lower = dimension_lower(actual_dim);
2682  expression actual_upper = dimension_upper(actual_dim);
2683  expression dummy_size, actual_size;
2684  if (expression_equal_integer_p(dummy_lower,1) &&
2685  expression_equal_integer_p(actual_lower,1))
2686  {
2687  dummy_size = copy_expression(dummy_upper);
2688  actual_size = copy_expression(actual_upper);
2689  }
2690  else
2691  {
2693  dummy_upper,dummy_lower);
2695  actual_upper,actual_lower);
2696  }
2697  if (expression_equal_in_context_p(actual_size, dummy_size, context))
2698  {
2699  if (l_actual_ref == NIL)
2700  // case : array name
2701  return true;
2702  else
2703  {
2704  // the actual argument is an array element name,
2705  // we have to calculate the subscript value also*/
2706  expression actual_sub = find_ith_argument(l_actual_ref,i);
2707  if (same_expression_p(actual_sub,actual_lower))
2708  return true;
2709  }
2710  }
2711  }
2712  return false;
2713 }
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
#define MINUS_OPERATOR_NAME
#define binary_intrinsic_expression(name, e1, e2)
bool expression_equal_integer_p(expression exp, int i)
================================================================
Definition: expression.c:1977
bool same_expression_p(expression e1, expression e2)
this is slightly different from expression_equal_p, as it will return true for a+b vs b+a
Definition: expression.c:1426
dimension find_ith_dimension(list, int)
This function returns the ith dimension of a list of dimensions.
Definition: type.c:5621
#define dimension_lower(x)
Definition: ri.h:980
#define dimension_upper(x)
Definition: ri.h:982
Definition: delay.c:253
static bool expression_equal_in_context_p(expression e1, expression e2, transformer context)
Fast checks :
Definition: transformer.c:2600

References binary_intrinsic_expression, copy_expression(), dimension_lower, dimension_upper, entity_type, expression_equal_in_context_p(), expression_equal_integer_p(), find_ith_argument(), find_ith_dimension(), gen_length(), MINUS_OPERATOR_NAME, NIL, same_expression_p(), type_variable, and variable_dimensions.

Referenced by interprocedural_abc_arrays().

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

◆ sc_eliminate_constant_terms()

Psysteme sc_eliminate_constant_terms ( Psysteme  sc,
Pvecteur  v 
)

Eliminate all constant terms in sc using v.

No sharing between sc and v is assumed as sc is updated!

This function should be located in Linear/sc

Parameters
scc

Definition at line 853 of file fix_point.c.

854 {
855  int cv = vect_coeff(TCST, v);
856 
857  assert(cv!=0);
858 
859  sc_egalites(sc) = constraints_eliminate_constant_terms(sc_egalites(sc), v);
860  sc_inegalites(sc) = constraints_eliminate_constant_terms(sc_inegalites(sc), v);
861 
862  return sc;
863 }
Pcontrainte constraints_eliminate_constant_terms(Pcontrainte lc, Pvecteur v)
Definition: fix_point.c:865
#define assert(ex)
Definition: newgen_assert.h:41

References assert, constraints_eliminate_constant_terms(), TCST, and vect_coeff().

Referenced by transformer_pattern_fix_point().

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

◆ sc_keep_invariants_only()

Psysteme sc_keep_invariants_only ( Psysteme  sc)

This function cannot be moved into the Linear library.

It relies on the concepts of old and new values.

It could be improved by using an approximate initial fix-point to evaluate v_sum (see invariant_vector_p) and to degrade equations into inequalities or to relax inequalities.

For instance, p = p + a won't generate an invariant. However, if the lousy fix-point is sufficient to prove a >= 0, it is possible to derive p::new >= p::old. Or even better if a's value turns out to be known.

Parameters
scc

Definition at line 902 of file fix_point.c.

903 {
904  sc_egalites(sc) = constraints_keep_invariants_only(sc_egalites(sc));
905  sc_inegalites(sc) = constraints_keep_invariants_only(sc_inegalites(sc));
906  return sc;
907 }
Pcontrainte constraints_keep_invariants_only(Pcontrainte lc)
Definition: fix_point.c:910

References constraints_keep_invariants_only().

Referenced by transformer_pattern_fix_point().

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

◆ sc_multiply_constant_terms()

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 which is not in sc's basis, and ik is added to the basis is necessary.

This possible only if ik is positive. Constraint ik>=0 is added if star_p is true because the function is used to compute T*. Else, contraint ik>=1 is added because the function is used to compute T+.

Also used in transformer_list.c

add constraint ik >= 0 to compute T*. Would be ik>=1 if T+ were sought.

Parameters
scc
ikk
star_ptar_p

Definition at line 1013 of file fix_point.c.

1014 {
1015  Pcontrainte c;
1016 
1017  pips_assert("sc is defined", !SC_UNDEFINED_P(sc));
1018  pips_assert("ik is not in sc's basis",
1019  !base_contains_variable_p(sc->base, ik));
1020 
1021  for(c = sc->egalites; !CONTRAINTE_UNDEFINED_P(c); c = c->succ) {
1022  Pvecteur v = c->vecteur;
1023  for(;!VECTEUR_NUL_P(v); v = v->succ) {
1024  Variable var = var_of(v);
1025  if(var==TCST) {
1026  var_of(v) = ik;
1027  break;
1028  }
1029  }
1030  }
1031 
1032  for(c = sc->inegalites; !CONTRAINTE_UNDEFINED_P(c); c = c->succ) {
1033  Pvecteur v = c->vecteur;
1034  for(;!VECTEUR_NUL_P(v); v = v->succ) {
1035  Variable var = var_of(v);
1036  if(var==TCST) {
1037  var_of(v) = ik;
1038  break;
1039  }
1040  }
1041  }
1042 
1043  /* add constraint ik >= 0 to compute T*. Would be ik>=1 if T+ were
1044  sought. */
1045  Pvecteur v = vect_new(ik, VALUE_MONE);
1046  if(!star_p) {
1047  // add the constant term for T+
1049  }
1050  c = contrainte_make(v);
1051  sc_add_inegalite(sc, c);
1052  base_add_dimension(&(sc->base), ik);
1053  sc->dimension++;
1054 
1055  return sc;
1056 }
void sc_add_inegalite(Psysteme p, Pcontrainte i)
void sc_add_inegalite(Psysteme p, Pcontrainte i): macro ajoutant une inegalite i a un systeme p; la b...
Definition: sc_alloc.c:406
Pvecteur vecteur
Pcontrainte inegalites
Definition: sc-local.h:71
Pcontrainte egalites
Definition: sc-local.h:70
#define var_of(varval)
#define base_add_dimension(b, v)

References Ssysteme::base, base_add_dimension, base_contains_variable_p(), contrainte_make(), CONTRAINTE_UNDEFINED_P, Ssysteme::dimension, Ssysteme::egalites, Ssysteme::inegalites, pips_assert, sc_add_inegalite(), Scontrainte::succ, Svecteur::succ, TCST, VALUE_MONE, VALUE_ONE, var_of, vect_add_elem(), vect_new(), Scontrainte::vecteur, and VECTEUR_NUL_P.

Referenced by transformer_derivative_fix_point(), and transformer_list_generic_transitive_closure().

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

◆ set_analyzed_types()

void set_analyzed_types ( void  )

Definition at line 271 of file value.c.

272 {
274  get_bool_property("SEMANTICS_ANALYZE_SCALAR_INTEGER_VARIABLES");
276  get_bool_property("SEMANTICS_ANALYZE_SCALAR_BOOLEAN_VARIABLES");
278  get_bool_property("SEMANTICS_ANALYZE_SCALAR_STRING_VARIABLES");
280  get_bool_property("SEMANTICS_ANALYZE_SCALAR_FLOAT_VARIABLES");
282  get_bool_property("SEMANTICS_ANALYZE_SCALAR_COMPLEX_VARIABLES");
284  get_bool_property("SEMANTICS_ANALYZE_SCALAR_POINTER_VARIABLES");
286  get_bool_property("SEMANTICS_ANALYZE_CONSTANT_PATH");
287 }
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....

References analyze_boolean_scalar_entities, analyze_complex_scalar_entities, analyze_constant_path, analyze_float_scalar_entities, analyze_integer_scalar_entities, analyze_pointer_scalar_entities, analyze_string_scalar_entities, and get_bool_property().

Referenced by eval_linear_expression(), and module_to_value_mappings().

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

◆ simple_addition_to_transformer()

transformer simple_addition_to_transformer ( entity  e,
entity  e1,
entity  e2,
bool  addition_p 
)

e and e1 and e2 are assumed to be values.

State e=e1+e2 or e=e1-e2. Type independent.

Parameters
e11
e22
addition_pddition_p

Definition at line 106 of file transformer.c.

110 {
113  Pcontrainte c;
114 
115  ifdebug(9) {
116  pips_debug(9, "entity e: %s, entity e1: %s, entity e2: %s, %s\n",
118  entity_local_name(e1),
119  entity_local_name(e2),
120  addition_p? "Is an addition" : "Is a subtraction");
121  }
122 
124  vect_add_elem(&eq, (Variable) e2, addition_p? VALUE_MONE : VALUE_ONE);
125  c = contrainte_make(eq);
126  tf = make_transformer(NIL,
128 
129  ifdebug(9) {
130  pips_debug(9, "end with tf=%p\n", tf);
131  dump_transformer(tf);
132  }
133 
134  return tf;
135 }

References contrainte_make(), CONTRAINTE_UNDEFINED, dump_transformer, entity_local_name(), eq, ifdebug, make_predicate(), make_transformer(), NIL, pips_debug, sc_make(), transformer_undefined, VALUE_MONE, VALUE_ONE, vect_add_elem(), and vect_new().

Referenced by addition_operation_to_transformer().

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

◆ simple_equality_to_transformer()

transformer simple_equality_to_transformer ( entity  e,
entity  f,
bool  assignment 
)

◆ simple_unary_minus_to_transformer()

transformer simple_unary_minus_to_transformer ( entity  e,
entity  f 
)

Definition at line 65 of file transformer.c.

66 {
67  transformer tf = generic_equality_to_transformer(e, f, false, true);
68 
69  return tf;
70 }

References f(), and generic_equality_to_transformer().

Referenced by unary_minus_operation_to_transformer().

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

◆ simplify_float_constraint()

Pvecteur simplify_float_constraint ( Pvecteur  v,
bool  is_equation_p 
)

If v is a not a float constraint, retun v.

If v is a float constraint, merge all float constants. If the constraint is trivially satisfied, return a NULL vector.

An integer constant cannot be mixed with floating point values

x!=0.

FI: do we want to represent 0. by 0?

Check that v is a feasible constraint

The new term must be the only one since vx is a new entity whose term cannot be cancelled by vect_add()

Unfeasible constraint

Parameters
is_equation_ps_equation_p

Definition at line 2061 of file transformer.c.

2062 {
2063  long double x = 0.;
2064  int occ = 0;
2065  bool is_float = true; // maybe a float constraint
2067  Pvecteur nv = VECTEUR_NUL;
2068 
2069  for(cv=v; !VECTEUR_UNDEFINED_P(cv) && is_float; cv = vecteur_succ(cv)) {
2070  entity e = (entity) vecteur_var(cv);
2071  Value val = vecteur_val(cv);
2072 
2073  if((Variable) e == TCST) {
2074  /* An integer constant cannot be mixed with floating point
2075  values */
2076  // pips_assert("x is zero", x==0.);
2077  is_float = false;
2078  }
2079  else if(entity_constant_p(e)) {
2080  if(float_constant_p(e)) {
2081  double d = float_constant_to_double(e);
2082  x += (long double)(val) * (long double) (d);
2083  occ++;
2084  if(val!=1)
2085  occ++;
2086  vect_add_elem(&nv, (Variable) e, -val);
2087  }
2088  else
2089  is_float = false;
2090  }
2091  else {
2092  type t = entity_type(e);
2093  if(float_type_p(t)) {
2094  ;
2095  }
2096  else {
2097  is_float = false;
2098  }
2099  }
2100  }
2101 
2102  if(is_float && vect_size(nv) > 0 && occ > 1 /* x!=0. */) {
2103  /* FI: do we want to represent 0. by 0? */
2104  if(x!=0.) {
2105  // FI: awfull precision loss...
2106  entity vx = float_to_entity((float) x>0?x:-x);
2107  // FI: let's try to move the constants on the right side,
2108  // i.e. the constant side, of the constraints
2109  // Might be independent of the constant sign
2110  // Avoid -(-6.) if a term is moved from one side to the other
2111  if(x>0)
2112  vect_add_elem(&nv, (Variable) vx, VALUE_ONE);
2113  else
2114  vect_add_elem(&nv, (Variable) vx, VALUE_MONE);
2115  }
2116  Pvecteur sv = vect_add(v, nv);
2117  vect_rm(v);
2118  vect_rm(nv);
2119  v = sv;
2120  }
2121 
2122  /* Check that v is a feasible constraint */
2123  if(vect_size(v)==1) {
2124  entity e = (entity) vecteur_var(v);
2125  /* The new term must be the only one since vx is a new entity
2126  whose term cannot be cancelled by vect_add() */
2127  if(e != (entity) TCST && entity_constant_p(e)) {
2128  if((!is_equation_p && x >0)
2129  || (is_equation_p && x!=0.)) {
2130  /* Unfeasible constraint */
2132  vect_rm(v);
2133  v = nv;
2134  }
2135  else {
2136  vect_rm(v);
2137  v = VECTEUR_NUL;
2138  }
2139  }
2140  }
2141 
2142  return v;
2143 }
double float_constant_to_double(entity c)
Definition: constant.c:639
entity float_to_entity(float c)
Definition: constant.c:430
bool float_constant_p(entity ent)
ent can be either a numerical or a symbolic float constant
Definition: constant.c:487
bool float_type_p(type)
Definition: type.c:3263
static char * x
Definition: split_file.c:159

References entity_constant_p, entity_type, float_constant_p(), float_constant_to_double(), float_to_entity(), float_type_p(), TCST, VALUE_MONE, VALUE_ONE, vect_add(), vect_add_elem(), vect_new(), vect_rm(), vect_size(), VECTEUR_NUL, vecteur_succ, VECTEUR_UNDEFINED, VECTEUR_UNDEFINED_P, vecteur_val, vecteur_var, and x.

Referenced by simplify_float_constraint_system().

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

◆ simplify_float_constraint_system()

Psysteme simplify_float_constraint_system ( Psysteme  ps)

Simplify float constraints and possibly detect.

Recompute the base, most of the time useless, but you cannot guess what happened in simplify_float_constraint()

Do not discard old values due to arguments... Just in case, keep too many floating point constants in the base. But add the new ones.

Parameters
pss

Definition at line 2146 of file transformer.c.

2147 {
2148  Pcontrainte eq;
2149 
2150  for (eq = ps->egalites; eq != NULL; eq=eq->succ) {
2151  if (eq->vecteur) {
2153  }
2154  }
2155  for (eq = ps->inegalites; eq != NULL; eq=eq->succ) {
2156  if (eq->vecteur) {
2158  }
2159  }
2160 
2161  /* Recompute the base, most of the time useless, but you cannot
2162  guess what happened in simplify_float_constraint() */
2163  Pbase ob = sc_base(ps);
2164  Pbase nb = sc_to_minimal_basis(ps);
2165  /* Do not discard old values due to arguments... Just in case, keep
2166  too many floating point constants in the base. But add the new
2167  ones. */
2168  sc_base(ps) = base_union(ob, nb);
2169  sc_dimension(ps) = base_dimension(sc_base(ps));
2170  vect_rm(ob);
2171  vect_rm(nb);
2172 
2173  ifdebug(1) pips_assert("sc is consistent", sc_consistent_p(ps));
2174 
2175  return ps;
2176 }
Pbase base_union(Pbase b1, Pbase b2)
Pbase base_union(Pbase b1, Pbase b2): compute a new basis containing all elements of b1 and all eleme...
Definition: base.c:428
bool sc_consistent_p(Psysteme sc)
bool sc_consistent_p(Psysteme sc): check that sc is well defined, that the numbers of equalities and ...
Definition: sc.c:282
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
return(s1)
Pvecteur simplify_float_constraint(Pvecteur v, bool is_equation_p)
If v is a not a float constraint, retun v.
Definition: transformer.c:2061
#define base_dimension(b)

References base_dimension, base_union(), Ssysteme::egalites, eq, ifdebug, Ssysteme::inegalites, pips_assert, sc_consistent_p(), sc_to_minimal_basis(), simplify_float_constraint(), Scontrainte::succ, vect_rm(), and Scontrainte::vecteur.

Referenced by transformer_normalize().

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

◆ sizeof_value_entity_p()

bool sizeof_value_entity_p ( entity  e)

Definition at line 969 of file value.c.

970 {
971  string s = strstr(entity_local_name(e), SIZEOF_SUFFIX);
972 
973  return s!=NULL;
974 }

References entity_local_name(), and SIZEOF_SUFFIX.

Referenced by have_sizeof_value_in_multiply_pointer_expression_p(), pips_user_value_name(), and value_to_variable().

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

◆ string_analyzed_p()

bool string_analyzed_p ( void  )

Definition at line 310 of file value.c.

311 {
313 }

References analyze_string_scalar_entities.

Referenced by any_expression_to_transformer(), fortran_data_to_prec_for_variables(), and parametric_transformer_empty_p().

+ Here is the caller graph for this function:

◆ sub_basis_p()

bool sub_basis_p ( Pbase  b1,
Pbase  b2 
)

FI: should be moved in base.c.

sub_basis_p(Pbase b1, Pbase b2): check if b1 is included in b2

Parameters
b11
b22

Definition at line 648 of file fix_point.c.

649 {
650  bool is_a_sub_basis = true;
651  Pbase t;
652 
653  for(t=b1; !VECTEUR_UNDEFINED_P(t) && is_a_sub_basis; t = t->succ) {
654  is_a_sub_basis = base_contains_variable_p(b2, vecteur_var(t));
655  }
656 
657  return is_a_sub_basis;
658 }

References b1, b2, base_contains_variable_p(), Svecteur::succ, VECTEUR_UNDEFINED_P, and vecteur_var.

Referenced by build_transfer_equations().

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

◆ test_mapping_entry_consistency()

void test_mapping_entry_consistency ( void  )

This second assert is too strong when some analyzable variables are equivalenced together. The number of values required is smaller since two (or more) different variables share the same value: the number of entries in the tables is greater than the number of values. We must compute the number of values in each table.

Why greater instead of equal? Because the equivalence variable appears in the equivalence equations although it should never appear in regular constraints, except under its canonical name.

Definition at line 1113 of file value.c.

1114 {
1115  int nbo = 0;
1116  int nbi = 0;
1117  int nbn = 0;
1118 
1119  pips_assert("The number of old values is equal to the number of intermediate values",
1122  /* This second assert is too strong when some analyzable variables are
1123  equivalenced together. The number of values required is smaller
1124  since two (or more) different variables share the same value: the
1125  number of entries in the tables is greater than the number of
1126  values. We must compute the number of values in each table.
1127  */
1128  /*
1129  pips_assert("The number of values is greater than the number"
1130  " of new, old and intermediate values",
1131  hash_table_entry_count(hash_value_to_name) >=
1132  hash_table_entry_count(hash_entity_to_new_value)
1133  + nbo + nbi);
1134  */
1138 
1139  /* Why greater instead of equal? Because the equivalence variable
1140  appears in the equivalence equations although it should never
1141  appear in regular constraints, except under its canonical name. */
1142  pips_assert("The number of values with a name is greater than the number"
1143  " of new, old and intermediate values",
1145  nbn + nbo + nbi);
1146 }
static int mapping_to_value_number(hash_table h)
Definition: value.c:1024

References hash_entity_to_intermediate_value, hash_entity_to_new_value, hash_entity_to_old_value, hash_table_entry_count(), hash_value_to_name, mapping_to_value_number(), and pips_assert.

Referenced by module_to_value_mappings().

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

◆ transfer_equation_p()

bool transfer_equation_p ( Pvecteur  eq)

A transfer equation is an explicit equation giving one new value as a function of old values and a constant term.

Because we are using diophantine equations, the coefficient of the new value must one or minus one. We assume that the equation is reduced (i.e. gcd(coeffs) == 1).

FI: Non-unary coefficients may appear because equations were combined, for instance by a previous internal fix-point as in KINETI of mdg-fi.f (Perfect Club). Maybe, something could be done for these nested fix-points.

Parameters
eqq

Definition at line 552 of file fix_point.c.

553 {
554  Pvecteur t;
555  int n_new = 0;
556  Value coeff = VALUE_ZERO;
557 
558  for(t=eq; !VECTEUR_UNDEFINED_P(t) && n_new <= 1; t = t->succ) {
559  entity e = (entity) vecteur_var(t);
560 
561  if( e != (entity) TCST && new_value_entity_p(e)) {
562  coeff = vecteur_val(t);
563  n_new++;
564  }
565  }
566 
567  return (n_new==1) && (value_one_p(coeff) || value_mone_p(coeff));
568 }

References eq, new_value_entity_p(), Svecteur::succ, TCST, value_mone_p, value_one_p, VALUE_ZERO, VECTEUR_UNDEFINED_P, vecteur_val, and vecteur_var.

Referenced by build_transfer_equations().

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

◆ transformer_add_3d_affine_constraint()

transformer transformer_add_3d_affine_constraint ( transformer  tf,
int  a1,
entity  v1,
int  a2,
entity  v2,
int  a3,
entity  v3,
int  cst,
bool  equation_p 
)

Add the constraint a1 v1 + a2 v2 + a3 v3 + cst <= or == 0.

Parameters
tff
a11
v11
a22
v22
a33
v33
cstst
equation_pquation_p

Definition at line 536 of file basic.c.

537 {
538  Pvecteur eq = vect_new((Variable) v1, (Value) a1);
539  vect_add_elem(&eq, (Variable) v2, (Value) a2);
540  vect_add_elem(&eq, (Variable) v3, (Value) a3);
541  vect_add_elem(&eq, TCST, (Value) cst);
542 
543  if(equation_p)
544  tf = transformer_equality_add(tf, eq);
545  else
546  tf = transformer_inequality_add(tf, eq);
547 
548  return tf;
549 }
transformer transformer_inequality_add(transformer tf, Pvecteur i)
Definition: basic.c:375

References eq, TCST, transformer_equality_add(), transformer_inequality_add(), vect_add_elem(), and vect_new().

Referenced by process_bounds_for_divide(), and update_cp_with_rhs_to_transformer().

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

◆ transformer_add_equality()

transformer transformer_add_equality ( transformer  tf,
entity  v1,
entity  v2 
)

Add an equality between two values (two variables?)

Parameters
tff
v11
v22

Definition at line 436 of file basic.c.

437 {
438  Pvecteur eq = vect_new((Variable) v1, (Value) 1);
439 
440  //pips_assert("v1 has values", entity_has_values_p(v1));
441  //pips_assert("v2 has values", entity_has_values_p(v2));
442 
444  tf = transformer_equality_add(tf, eq);
445 
446  return tf;
447 }

References eq, transformer_equality_add(), VALUE_MONE, vect_add_elem(), and vect_new().

Referenced by any_basic_update_operation_to_transformer(), assign_operation_to_transformer(), generic_abs_to_transformer(), generic_reference_to_transformer(), generic_unary_operation_to_transformer(), lhs_expression_to_transformer(), transformer_apply_field_assignments_or_equalities(), and update_operation_to_transformer().

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

◆ transformer_add_equality_with_affine_term()

transformer transformer_add_equality_with_affine_term ( transformer  tf,
entity  v,
entity  x,
int  a,
int  cst 
)

Add the equality v = a x + cst.

Parameters
tff
cstst

Definition at line 517 of file basic.c.

518 {
520 
521  vect_add_elem(&eq, (Variable) x, (Value) -a);
522  vect_add_elem(&eq, TCST, (Value) -cst);
523 
524  tf = transformer_equality_add(tf, eq);
525 
526  return tf;
527 }

References eq, TCST, transformer_equality_add(), VALUE_ONE, vect_add_elem(), vect_new(), and x.

Referenced by generic_abs_to_transformer().

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

◆ transformer_add_equality_with_integer_constant()

transformer transformer_add_equality_with_integer_constant ( transformer  tf,
entity  v,
long long int  cst 
)

Add an equality between a value and an integer constant: v==cst.

Parameters
tff
cstst

Definition at line 450 of file basic.c.

451 {
453 
454  //pips_assert("v1 has values", entity_has_values_p(v1));
455  //pips_assert("v2 has values", entity_has_values_p(v2));
456 
457  vect_add_elem(&eq, TCST, (Value) cst);
458  tf = transformer_equality_add(tf, eq);
459 
460  return tf;
461 }

References eq, TCST, transformer_equality_add(), VALUE_MONE, vect_add_elem(), and vect_new().

Referenced by add_type_information(), bitwise_xor_to_transformer(), constant_to_transformer(), generic_abs_to_transformer(), integer_expression_to_transformer(), integer_left_shift_to_transformer(), integer_power_to_transformer(), logical_binary_function_to_transformer(), logical_expression_to_transformer(), logical_not_to_transformer(), modulo_by_a_constant_to_transformer(), modulo_of_a_constant_to_transformer(), and transformer_add_condition_information_updown().

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

◆ transformer_add_identity()

transformer transformer_add_identity ( transformer  tf,
entity  v 
)
Parameters
tff

Definition at line 421 of file basic.c.

422 {
423  entity v_new = entity_to_new_value(v);
424  entity v_old = entity_to_old_value(v);
425  Pvecteur eq = vect_new((Variable) v_new, (Value) 1);
426 
427  vect_add_elem(&eq, (Variable) v_old, (Value) -1);
428  tf = transformer_equality_add(tf, eq);
431 
432  return tf;
433 }

References arguments_add_entity(), entity_to_new_value(), entity_to_old_value(), eq, transformer_arguments, transformer_equality_add(), vect_add_elem(), and vect_new().

+ Here is the call graph for this function:

◆ transformer_add_inequality()

transformer transformer_add_inequality ( transformer  tf,
entity  v1,
entity  v2,
bool  strict_p 
)

Add the equality v1 <= v2 or v1 < v2.

Parameters
tff
v11
v22
strict_ptrict_p

Definition at line 464 of file basic.c.

465 {
467 
469  if(strict_p)
471  tf = transformer_inequality_add(tf, eq);
472 
473  return tf;
474 }

References eq, TCST, transformer_inequality_add(), VALUE_MONE, VALUE_ONE, vect_add_elem(), and vect_new().

Referenced by add_index_bound_conditions(), integer_left_shift_to_transformer(), and integer_multiply_to_transformer().

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

◆ transformer_add_inequality_with_affine_term()

transformer transformer_add_inequality_with_affine_term ( transformer  tf,
entity  v,
entity  x,
int  a,
int  cst,
bool  less_than_p 
)

Add the inequality v <= a x + cst or v >= a x + cst.

Parameters
tff
cstst
less_than_pess_than_p

Definition at line 496 of file basic.c.

497 {
499 
500  if(less_than_p) {
501  eq = vect_new((Variable) v, VALUE_ONE);
502  vect_add_elem(&eq, (Variable) x, (Value) -a);
503  vect_add_elem(&eq, TCST, (Value) -cst);
504  }
505  else {
506  eq = vect_new((Variable) v, VALUE_MONE);
507  vect_add_elem(&eq, TCST, (Value) cst);
508  vect_add_elem(&eq, (Variable) x, (Value) a);
509  }
510 
511  tf = transformer_inequality_add(tf, eq);
512 
513  return tf;
514 }

References eq, TCST, transformer_inequality_add(), VALUE_MONE, VALUE_ONE, vect_add_elem(), vect_new(), VECTEUR_NUL, and x.

Referenced by integer_left_shift_to_transformer(), integer_multiply_to_transformer(), and transformer_add_inequality_with_linear_term().

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

◆ transformer_add_inequality_with_integer_constraint()

transformer transformer_add_inequality_with_integer_constraint ( transformer  tf,
entity  v,
long long int  cst,
bool  less_than_p 
)

Add the inequality v <= cst or v >= cst.

Parameters
tff
cstst
less_than_pess_than_p

Definition at line 477 of file basic.c.

478 {
480 
481  if(less_than_p) {
482  eq = vect_new((Variable) v, VALUE_ONE);
483  vect_add_elem(&eq, TCST, (Value) -cst);
484  }
485  else {
486  eq = vect_new((Variable) v, VALUE_MONE);
487  vect_add_elem(&eq, TCST, (Value) cst);
488  }
489 
490  tf = transformer_inequality_add(tf, eq);
491 
492  return tf;
493 }

References eq, TCST, transformer_inequality_add(), VALUE_MONE, VALUE_ONE, vect_add_elem(), and vect_new().

Referenced by add_type_information(), integer_call_expression_to_transformer(), integer_left_shift_to_transformer(), integer_minmax_to_transformer(), integer_power_to_transformer(), logical_binary_function_to_transformer(), logical_not_to_transformer(), modulo_by_a_constant_to_transformer(), modulo_of_a_constant_to_transformer(), modulo_of_a_negative_value_to_transformer(), modulo_of_a_positive_value_to_transformer(), and modulo_to_transformer().

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

◆ transformer_add_inequality_with_linear_term()

transformer transformer_add_inequality_with_linear_term ( transformer  tf,
entity  v,
entity  x,
int  a,
bool  less_than_p 
)

Add the inequality v <= a x or v >= a x.

Parameters
tff
less_than_pess_than_p

Definition at line 530 of file basic.c.

531 {
532  return transformer_add_inequality_with_affine_term(tf, v, x, a, VALUE_ZERO, less_than_p);
533 }
transformer transformer_add_inequality_with_affine_term(transformer tf, entity v, entity x, int a, int cst, bool less_than_p)
Add the inequality v <= a x + cst or v >= a x + cst.
Definition: basic.c:496

References transformer_add_inequality_with_affine_term(), VALUE_ZERO, and x.

Referenced by expression_multiply_sizeof_to_transformer(), integer_multiply_to_transformer(), and loop_to_enter_transformer().

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

◆ transformer_add_modified_variable()

transformer transformer_add_modified_variable ( transformer  tf,
entity  var 
)

FI: this function does not end up with a consistent transformer because the old value is not added to the basis of sc.

Also, the variable should be transformed into a new value... See next function.

Should we check that var has values?

Parameters
tff
varar

Definition at line 889 of file basic.c.

892 {
893  /* Should we check that var has values? */
895  Pbase b = sc_base(sc);
896 
898  sc_base(sc) = vect_add_variable(b, (Variable) var);
899  sc_dimension(sc) = base_dimension(sc_base(sc));
900 
901  return tf;
902 }

References arguments_add_entity(), base_dimension, predicate_system, transformer_arguments, transformer_relation, and vect_add_variable().

Referenced by any_assign_operation_to_transformer(), any_scalar_assign_to_transformer_list(), any_scalar_assign_to_transformer_without_effect(), transformer_apply_field_assignments_or_equalities(), and transformer_apply_unknown_field_assignments_or_equalities().

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

◆ transformer_add_modified_variable_entity()

transformer transformer_add_modified_variable_entity ( transformer  tf,
entity  var 
)

FI: like the previous function, but supposed to end up with a consistent transformer.

When the transformer is empty/unfeasible, the variable is not added to conform to rules about standard empty transformer: how could a variable be updated by a non-existing transition?

FI: it is not well specifived if the argument should be made of new values or of progtram variables because up to now the two are the same, except when printed out.

Parameters
tff
varar

Definition at line 909 of file basic.c.

911 {
912  if(!transformer_empty_p(tf)) {
914  Pbase b = sc_base(sc);
915 
916  if(entity_has_values_p(var)) {
917  entity v_new = entity_to_new_value(var);
918  entity v_old = entity_to_old_value(var);
919 
920  /* FI: it is not well specifived if the argument should be made
921  of new values or of progtram variables because up to now the
922  two are the same, except when printed out. */
924  sc_base(sc) = vect_add_variable(b, (Variable) v_new);
925  sc_base(sc) = vect_add_variable(sc_base(sc), (Variable) v_old);
926  sc_dimension(sc) = base_dimension(sc_base(sc));
927  }
928  else
929  pips_internal_error("Entity \"%s\" has no values.", entity_name(var));
930  }
931 
932  return tf;
933 }
bool entity_has_values_p(entity)
This function could be made more robust by checking the storage of e.
Definition: value.c:911

References arguments_add_entity(), base_dimension, entity_has_values_p(), entity_name, entity_to_new_value(), entity_to_old_value(), pips_internal_error, predicate_system, transformer_arguments, transformer_empty_p(), transformer_relation, and vect_add_variable().

Referenced by safe_assigned_expression_to_transformer(), and safe_assigned_expression_to_transformer_list().

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

◆ transformer_add_sign_information()

transformer transformer_add_sign_information ( transformer  tf,
entity  v,
int  v_sign 
)

CHANGE THIS NAME: no loop index please, it's not directly linked to loops!!!

Add in tf the information that v is striclty positive, strictly negative or zero.

Assume that v is a value and tf is defined.

v_sign<0

v_sign==0

Parameters
tff
v_sign_sign

Definition at line 200 of file basic.c.

203 {
205 
206  ifdebug(1) {
207  pips_assert("Transformer tf is consistent on entrance",
209  }
210 
212 
213  psyst->base = base_add_variable(psyst->base, (Variable) v);
214  psyst->dimension = base_dimension(psyst->base);
215 
216  if(v_sign!=0) {
217  Pvecteur cv;
218  Pcontrainte ineq;
219  if(v_sign>0) {
220  cv = vect_new((Variable) v, VALUE_MONE);
222  }
223  else {
224  /* v_sign<0 */
225  cv = vect_new((Variable) v, VALUE_ONE);
227  }
228  ineq = contrainte_make(cv);
229  sc_add_inegalite(psyst, ineq);
230  }
231  else {
232  /* v_sign==0*/
233  Pvecteur cv = vect_new((Variable) v, VALUE_ONE);
235 
236  sc_add_egalite(psyst, eq);
237  }
238 
239  ifdebug(1) {
240  pips_assert("Transformer tf is consistent on exit",
242  }
243 
244  return tf;
245 }
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
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

References Ssysteme::base, base_add_variable(), base_dimension, contrainte_make(), Ssysteme::dimension, eq, ifdebug, local_temporary_value_entity_p(), pips_assert, predicate_system, sc_add_egalite(), sc_add_inegalite(), TCST, transformer_consistency_p(), transformer_relation, value_entity_p(), VALUE_MONE, VALUE_ONE, vect_add_elem(), and vect_new().

Referenced by condition_to_transformer().

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

◆ transformer_add_value_update()

transformer transformer_add_value_update ( transformer  t,
entity  v 
)

Add an update of variable v to t (a value cannot be updated)

Definition at line 321 of file basic.c.

322 {
323  entity nv = entity_to_new_value(v);
324  entity ov = entity_to_old_value(v);
325 
326  if(!transformer_empty_p(t)) {
328 
330  if(!base_contains_variable_p(psyst->base, (Variable) nv))
331  psyst->base = base_add_variable(psyst->base, (Variable) nv);
332  if(!base_contains_variable_p(psyst->base, (Variable) ov))
333  psyst->base = base_add_variable(psyst->base, (Variable) ov);
334  psyst->dimension = vect_size(psyst->base);
335  }
336 
337  return t;
338 }

References arguments_add_entity(), Ssysteme::base, base_add_variable(), base_contains_variable_p(), Ssysteme::dimension, entity_to_new_value(), entity_to_old_value(), predicate_system, transformer_arguments, transformer_empty_p(), transformer_relation, and vect_size().

Referenced by assigned_expression_to_transformer(), assigned_expression_to_transformer_list(), c_return_to_transformer(), and transformer_add_variables_update().

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

◆ transformer_add_variable_incrementation()

transformer transformer_add_variable_incrementation ( transformer  t,
entity  i,
Pvecteur  incr 
)

transformer transformer_add_loop_index(transformer t, entity i, Pvecteur incr): add the index incrementation expression incr for loop index i to transformer t.

t = intersection(t, i::new = i::old + incr)

incr is supposed to be compatible with the value mappings

Pvecteur incr should not be used after a call to transformer_add_index because it is shared by t and modified

Psysteme * ps = &((Psysteme) predicate_system(transformer_relation(t)));

Parameters
incrncr

Definition at line 260 of file basic.c.

264 {
265  /* Psysteme * ps =
266  &((Psysteme) predicate_system(transformer_relation(t))); */
268  entity i_old = entity_to_old_value(i);
269  entity i_new = entity_to_new_value(i);
270  entity i_rep = value_to_variable(i_new);
271 
273  psyst->base = vect_add_variable(psyst->base, (Variable) i_new);
274  psyst->base = vect_add_variable(psyst->base, (Variable) i_old);
275  psyst->dimension = vect_size(psyst->base);
276  vect_chg_coeff(&incr, (Variable) i_new, -1);
277  vect_chg_coeff(&incr, (Variable) i_old, 1);
278  psyst = sc_equation_add(psyst, contrainte_make(incr));
279 
280  return t;
281 }
Psysteme sc_equation_add(Psysteme sc, Pcontrainte c)
The basis of the constraint system is updated.
Definition: sc_insert_eq.c:101
void vect_chg_coeff(Pvecteur *ppv, Variable var, Value val)
void vect_chg_coeff(Pvecteur *ppv, Variable var, Value val): mise de la coordonnee var du vecteur *pp...
Definition: unaires.c:143

References arguments_add_entity(), Ssysteme::base, contrainte_make(), Ssysteme::dimension, entity_to_new_value(), entity_to_old_value(), predicate_system, sc_equation_add(), transformer_arguments, transformer_relation, value_to_variable(), vect_add_variable(), vect_chg_coeff(), and vect_size().

Referenced by transformer_add_loop_index_incrementation().

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

◆ transformer_add_variable_update()

transformer transformer_add_variable_update ( transformer  t,
entity  v 
)

Add an update of variable v into t.

NL : this function is not finish do the same thing than transformer_add_value_update for the moment TODO

Definition at line 289 of file basic.c.

290 {
292  entity v_new = entity_to_new_value(v);
293  entity v_old = entity_to_old_value(v);
294  entity v_rep = value_to_variable(v_new);
295 
297  if(!base_contains_variable_p(psyst->base, (Variable) v_new)) {
298  psyst->base = base_add_variable(psyst->base, (Variable) v_new);
299  }
300  if(!base_contains_variable_p(psyst->base, (Variable) v_old)) {
301  psyst->base = base_add_variable(psyst->base, (Variable) v_old);
302  }
303  psyst->dimension = vect_size(psyst->base);
304 
305 //
306 // pips_assert("before value substitution\n", transformer_consistency_p(t));
307 //// t = transformer_value_substitute(t, v_new, v_old);
308 //
309 // pips_debug(9, "before tes\nt");
310 // if(base_contains_variable_p(psyst->base, (Variable) v_new)) {
311 // if(!base_contains_variable_p(psyst->base, (Variable) v_old)) {
312 // pips_debug(9, "rename variable\n");
313 // (void) sc_variable_rename(psyst,(Variable) v_new, (Variable)v_old);
314 // }
315 // }
316 // pips_assert("after value substitution\n", transformer_consistency_p(t));
317  return t;
318 }

References arguments_add_entity(), Ssysteme::base, base_add_variable(), base_contains_variable_p(), Ssysteme::dimension, entity_to_new_value(), entity_to_old_value(), predicate_system, transformer_arguments, transformer_relation, value_to_variable(), and vect_size().

Referenced by apply_abstract_effect_to_transformer(), apply_array_effect_to_transformer(), apply_concrete_effect_to_transformer(), generic_apply_effect_to_transformer(), and generic_reference_to_transformer().

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

◆ transformer_add_variables_update()

transformer transformer_add_variables_update ( transformer  t,
list  vl 
)
Parameters
vll

Definition at line 340 of file basic.c.

341 {
342  FOREACH(ENTITY, v, vl) {
344  }
345  return t;
346 }
transformer transformer_add_value_update(transformer t, entity v)
Add an update of variable v to t (a value cannot be updated)
Definition: basic.c:321

References ENTITY, FOREACH, and transformer_add_value_update().

Referenced by c_user_call_to_transformer().

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

◆ transformer_affect_linear_p()

bool transformer_affect_linear_p ( transformer  tf,
Pvecteur  l 
)

bool transformer_affect_linear_p(transformer tf, Pvecteur l): returns TRUE if there is a state s such that eval(l, s) != eval(l, tf(s)); returns false if l is invariant w.r.t.

tf, i.e. for all state s, eval(l, s) == eval(l, tf(s))

Parameters
tff

Definition at line 1850 of file transformer.c.

1851 {
1852  if (!transformer_undefined_p(tf)){
1853  list args = transformer_arguments(tf);
1854 
1855  MAP(ENTITY, e,
1856  {
1857  Value v = vect_coeff((Variable) e, l);
1858  if(value_notzero_p(v)) return true;
1859  },
1860  args);
1861  }
1862 
1863  return false;
1864 }
#define value_notzero_p(val)
#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 ENTITY, MAP, transformer_arguments, transformer_undefined_p, value_notzero_p, and vect_coeff().

Referenced by add_affine_bound_conditions(), add_loop_index_exit_value(), and transformer_affect_transformer_p().

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

◆ transformer_affect_transformer_p()

bool transformer_affect_transformer_p ( transformer  tf1,
transformer  tf2 
)

Transformer tf1 affects transformer tf2 if values modified by tf1 appear in any constraint of tf2.

The two transformer do not commute and tf1 o tf2 does not equal tf2 o tf1.

No need to check anything if tf1 does not change the memory state

Parameters
tf1f1
tf2f2

Definition at line 1870 of file transformer.c.

1871 {
1872  bool affect_p = false;
1873 
1874  /* No need to check anything if tf1 does not change the memory state */
1875  if(!ENDP(transformer_arguments(tf1))) {
1877  Pcontrainte ceq = sc_egalites(s2);
1878  Pcontrainte cineq = sc_inegalites(s2);
1879 
1880  for(; !CONTRAINTE_UNDEFINED_P(ceq) && !affect_p; ceq = contrainte_succ(ceq)) {
1881  Pvecteur v = contrainte_vecteur(ceq);
1882  affect_p = transformer_affect_linear_p(tf1, v);
1883  }
1884 
1885  for(; !CONTRAINTE_UNDEFINED_P(cineq) && !affect_p; cineq = contrainte_succ(cineq)) {
1886  Pvecteur v = contrainte_vecteur(cineq);
1887  affect_p = transformer_affect_linear_p(tf1, v);
1888  }
1889  }
1890 
1891  return affect_p;
1892 }
bool transformer_affect_linear_p(transformer tf, Pvecteur l)
bool transformer_affect_linear_p(transformer tf, Pvecteur l): returns TRUE if there is a state s such...
Definition: transformer.c:1850

References contrainte_succ, CONTRAINTE_UNDEFINED_P, contrainte_vecteur, ENDP, predicate_system, transformer_affect_linear_p(), transformer_arguments, and transformer_relation.

Referenced by transformer_safe_affect_transformer_p().

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

◆ transformer_apply()

transformer transformer_apply ( transformer  tf,
transformer  pre 
)

transformer transformer_apply(transformer tf, transformer pre): apply transformer tf on precondition pre to obtain postcondition post

post = tf(pre) = pre o tf

There is (should be!) no sharing between pre and tf. No sharing is introduced between pre or tf and post. Neither pre nor tf are modified.

post = tf o pre ; pre would be modified by transformer_combine

Parameters
tff
prere

Definition at line 1559 of file transformer.c.

1560 {
1561  transformer post;
1562  transformer copy_pre;
1563 
1564  pips_debug(8,"begin\n");
1565  pips_assert("tf is not undefined", tf!=transformer_undefined);
1566  pips_debug(8,"tf=%p\n", tf);
1567  ifdebug(8) (void) dump_transformer(tf);
1568  pips_assert("pre is not undefined", pre!=transformer_undefined);
1569  pips_debug(8,"pre=%p\n", pre);
1570  ifdebug(8) (void) dump_transformer(pre);
1571 
1572  /* post = tf o pre ; pre would be modified by transformer_combine */
1573  copy_pre = transformer_dup(pre);
1574  post = transformer_combine(copy_pre, tf);
1575 
1576  pips_assert("post is not undefined", post!=transformer_undefined);
1577  pips_debug(8,"post=%p\n", post);
1578  ifdebug(8) (void) dump_transformer(post);
1579  pips_assert("unexpected sharing",post != pre);
1580  pips_debug(8,"end\n");
1581 
1582  return post;
1583 }

References dump_transformer, ifdebug, pips_assert, pips_debug, transformer_combine(), transformer_dup(), and transformer_undefined.

Referenced by add_good_loop_conditions(), add_loop_index_exit_value(), add_loop_index_initialization(), addition_operation_to_transformer(), any_assign_to_transformer(), any_conditional_to_transformer(), any_expressions_to_transformer(), any_loop_to_k_transformer(), any_loop_to_postcondition(), any_transformer_to_k_closure(), any_user_call_site_to_transformer(), apply_transformer_lists_generic(), assign_rhs_to_reflhs_to_transformer(), bitwise_xor_to_transformer(), call_to_postcondition(), complete_forloop_transformer(), complete_forloop_transformer_list(), complete_loop_transformer(), complete_loop_transformer_list(), complete_repeatloop_transformer_list(), condition_to_transformer(), conditional_to_transformer(), cycle_to_flow_sensitive_preconditions(), dag_or_cycle_to_flow_sensitive_postconditions_or_transformers(), dag_to_flow_sensitive_preconditions(), declaration_to_transformer(), declaration_to_transformer_list(), dimensions_to_transformer(), expression_multiply_sizeof_to_transformer(), expression_to_postcondition(), expressions_to_transformer(), forloop_to_postcondition(), forloop_to_transformer(), integer_binary_operation_to_transformer(), integer_left_shift_to_transformer(), integer_multiply_to_transformer(), invariant_wrt_transformer(), loop_to_postcondition(), modulo_to_transformer(), new_add_formal_to_actual_bindings(), new_complete_whileloop_transformer_list(), new_loop_to_transformer(), precondition_minmax_of_expression(), process_ready_node(), repeatloop_to_postcondition(), statement_to_postcondition(), statement_to_transformer(), test_to_postcondition(), test_to_total_precondition(), test_to_transformer(), test_to_transformer_list(), transformer_add_any_relation_information(), transformer_add_condition_information_updown(), transformer_apply_generic(), transformer_list_closure_to_precondition_depth_two(), transformer_list_closure_to_precondition_max_depth(), transformer_safe_apply(), unstructured_to_postcondition(), unstructured_to_total_precondition(), whileloop_to_postcondition(), and whileloop_to_total_precondition().

+ Here is the call graph for this function:

◆ transformer_apply_generic()

list transformer_apply_generic ( list  tl,
transformer  pre,
bool  keep_p 
)

Generates a new list of postconditions, one for each transformer in tl, unless the postcondition is empty and keep_p is FALSE.

keep_p is used to preserve the list lengths: the output list is exactly as long as the input list.

If keep_p is true, the output list is not "normalized"

Parameters
tll
prere
keep_peep_p

Definition at line 1593 of file transformer.c.

1594 {
1595  list ntl = NIL;
1596  FOREACH(TRANSFORMER, tf, tl) {
1597  transformer post = transformer_apply(tf, pre);
1598 
1599  // Be careful with empty transformers that may creep out
1600 
1601  if(!transformer_empty_p(post) || keep_p)
1602  ntl = CONS(TRANSFORMER, post, ntl);
1603  }
1604  ntl = gen_nreverse(ntl);
1605  return ntl;
1606 }

References CONS, FOREACH, gen_nreverse(), NIL, TRANSFORMER, transformer_apply(), and transformer_empty_p().

Referenced by transformer_apply_map(), transformers_apply(), and transformers_apply_and_keep_all().

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

◆ transformer_apply_map()

list transformer_apply_map ( list  tl,
transformer  pre 
)

Generates a new list of postconditions, one for each transformer in tl, unless the postcondition is empty.

Parameters
tll
prere

Definition at line 1610 of file transformer.c.

1611 {
1612  return transformer_apply_generic(tl, pre, false);
1613 }
list transformer_apply_generic(list tl, transformer pre, bool keep_p)
Generates a new list of postconditions, one for each transformer in tl, unless the postcondition is e...
Definition: transformer.c:1593

References transformer_apply_generic().

Referenced by test_to_transformer_list().

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

◆ transformer_argument_consistency_p()

bool transformer_argument_consistency_p ( transformer  t)

Definition at line 551 of file basic.c.

552 {
554 }
bool transformer_argument_general_consistency_p(transformer t, bool is_weak)
Definition: basic.c:561

References transformer_argument_general_consistency_p().

Referenced by transformer_add_any_relation_information(), and transformer_general_consistency_p().

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

◆ transformer_argument_general_consistency_p()

bool transformer_argument_general_consistency_p ( transformer  t,
bool  is_weak 
)

If no final state can be reached, no variable can be changed in between

If a variable appears as argument, its new value must be in the basis See for instance, effects_to_transformer()

pips_user_warning("No value for argument %s in relation basis\n", entity_name(e));

Parameters
is_weaks_weak

Definition at line 561 of file basic.c.

562 {
563  list args = transformer_arguments(t);
564  bool consistent = true;
566  Pbase b = sc_base(sc);
567 
568  /* If no final state can be reached, no variable can be changed in between */
569  if(sc_empty_p(sc)) {
570  consistent = ENDP(args);
571  pips_assert("Empty transformer must have no arguments", consistent);
572  }
573  else if(!is_weak) {
574  /* If a variable appears as argument, its new value must be in the basis
575  * See for instance, effects_to_transformer()
576  */
577 
578  MAP(ENTITY, e, {
580  /*
581  pips_assert("Argument is in the basis", base_contains_variable_p(b, (Variable) v));
582  */
583  if(!base_contains_variable_p(b, (Variable) v)) {
584  /* pips_user_warning("No value for argument %s in relation basis\n",
585  entity_name(e)); */
586  pips_internal_error("No value for argument %s in relation basis",
587  entity_name(e));
588  consistent = false;
589  }
590  }, args);
591  pips_assert("Argument variables must have values in basis", consistent);
592  }
593 
594  return consistent;
595 }
bool sc_empty_p(Psysteme sc)
bool sc_empty_p(Psysteme sc): check if the set associated to sc is the constant sc_empty or not.
Definition: sc_alloc.c:350

References base_contains_variable_p(), ENDP, ENTITY, entity_name, entity_to_new_value(), MAP, pips_assert, pips_internal_error, predicate_system, sc_empty_p(), transformer_arguments, and transformer_relation.

Referenced by transformer_argument_consistency_p(), and transformer_argument_weak_consistency_p().

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

◆ transformer_argument_weak_consistency_p()

bool transformer_argument_weak_consistency_p ( transformer  t)

Definition at line 556 of file basic.c.

557 {
559 }

References transformer_argument_general_consistency_p().

+ Here is the call graph for this function:

◆ transformer_arguments_projection()

transformer transformer_arguments_projection ( transformer  t)

transformer transformer_projection(transformer t); projection of t along the hyperplane defined by values of variables in arguments; this generate a projection and not a cylinder based on the projection

use the most complex/complete redundancy elimination in Linear

args is not modified. t is modified by side effects.

Definition at line 1285 of file transformer.c.

1286 {
1287  list args = NIL;
1289  Pbase b = sc_base(sc);
1290 
1291  MAP(ENTITY, a, {
1292  entity ov = entity_to_old_value(a);
1293  entity nv = entity_to_new_value(a);
1294 
1295  if(base_contains_variable_p(b, (Variable) ov))
1296  args = CONS(ENTITY, ov, args);
1297  if(base_contains_variable_p(b, (Variable) nv))
1298  args = CONS(ENTITY, nv, args);
1299  }, transformer_arguments(t));
1300 
1301  t = transformer_projection(t, args);
1302  gen_free_list(args);
1303  return t;
1304 }

References base_contains_variable_p(), CONS, ENTITY, entity_to_new_value(), entity_to_old_value(), gen_free_list(), MAP, NIL, predicate_system, transformer_arguments, transformer_projection(), and transformer_relation.

+ Here is the call graph for this function:

◆ transformer_basic_fix_point()

transformer transformer_basic_fix_point ( transformer  tf)

Computation of a fix point: drop all constraints, remember which variables are changed.

Except if the transformer is syntactically empty since its fix point is easy to compute. Without normalization, mathematically empty transformers are lost.

get rid of equalities and inequalities but keep the basis

Parameters
tff

Definition at line 1280 of file fix_point.c.

1281 {
1282  transformer fix_tf = copy_transformer(tf);
1283 
1284  if(!transformer_empty_p(tf)) {
1285  /* get rid of equalities and inequalities but keep the basis */
1287  Pcontrainte eq = sc_egalites(sc);
1288  Pcontrainte ineq = sc_inegalites(sc);
1290  contraintes_free(ineq);
1291  sc_egalites(sc) = CONTRAINTE_UNDEFINED;
1292  sc_inegalites(sc) = CONTRAINTE_UNDEFINED;
1293  sc_nbre_egalites(sc) = 0;
1294  sc_nbre_inegalites(sc) = 0;
1295  }
1296 
1297  return fix_tf;
1298 }
Pcontrainte contraintes_free(Pcontrainte pc)
Pcontrainte contraintes_free(Pcontrainte pc): desallocation de toutes les contraintes de la liste pc.
Definition: alloc.c:226

References CONTRAINTE_UNDEFINED, contraintes_free(), copy_transformer(), eq, predicate_system, transformer_empty_p(), and transformer_relation.

Referenced by select_fix_point_operator().

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

◆ transformer_combine()

transformer transformer_combine ( volatile transformer  t1,
transformer  t2 
)

transformer transformer_combine(transformer t1, transformer t2): compute the composition of transformers t1 and t2 (t1 then t2)

t1 := t2 o t1 return t1

t1 is updated, but t2 is preserved

general algorithm: let a1 be t1 arguments, a2 be t2 arguments, let ints be the intersection of a1 and a2 let r1 be t1 relation and r2 be a copy of t2 relation let a be a1 union a2 rename entities in ints in r1 (new->int) and r2 (old->int) rename entities in a2-ints in r1 (new->old) build a system b with r1 and r2 project b along ints build t1 with a and b

Handling of four special cases because abstract effects are likely to generate rn transformers, which lead to lots of variable projections if handled as a usual transformer. Not sufficient to solve Ticket 644. But sufficient to introduce lots of bugs...

not much to do since t1 is going to destroy all information in t2, except its range

not much to do since t2 is going to destroy all information in t1, except its domain

Standard case

Newgen does not generate the proper castings

Automatic variables read in a CATCH block need to be declared volatile as specified by the documentation

ints: list of intermediate value entities

The consistencies of transformers t1 and t2 cannot be checked with respect to the current environment because t1 or t2 may be relative to a callee as in user_function_call_to_transformer(). Hence a debug level of 10.

both t1 and t2 are not obviously unfeasible

build new argument list and rename old and intermediate values, as well as new (i.e. unmodified) variables in t1

renaming of intermediate values in r1 and r2

if ever e2 is used as e2::new in r1 it must now be replaced by e2::old

e2 must be appended to a1 as new t1's arguments; hopefully we are not iterating on a1; but entity_is_argument_p() receives a longer argument each time; possible improvements?

build global linear system: r1 is destroyed, r2 is preserved

??? The base returned may be empty... FC... boumbadaboum in the projection later on.

get rid of intermediate values, if any. ??? guard added to avoid an obscure bug, but I guess it should never get here with en nil base... FC

CA

IER: problem with e_temp that should be volatile because of the catch structure. Not easy make it volatile because of the MAP MACRO

get rid of ints

update t1

No old values should be left in r1's basis.

Parameters
t11
t22

Definition at line 238 of file transformer.c.

239 {
240  /* general algorithm:
241  let a1 be t1 arguments, a2 be t2 arguments,
242  let ints be the intersection of a1 and a2
243  let r1 be t1 relation and r2 be a copy of t2 relation
244  let a be a1 union a2
245  rename entities in ints in r1 (new->int) and r2 (old->int)
246  rename entities in a2-ints in r1 (new->old)
247  build a system b with r1 and r2
248  project b along ints
249  build t1 with a and b
250  */
251  volatile list a1 = transformer_arguments(t1);
252  list a2 = transformer_arguments(t2);
254 
255  /* Handling of four special cases because abstract effects are
256  likely to generate rn transformers, which lead to lots of
257  variable projections if handled as a usual transformer. Not
258  sufficient to solve Ticket 644. But sufficient to introduce lots
259  of bugs... */
260  if(transformer_is_rn_p(t1) && !ENDP(wvl) && arguments_set_equal_p(a1, wvl)) {
261  if(transformer_is_empty_p(t2)) {
262  free_transformer(t1);
263  t1 = copy_transformer(t2); // t1 is empty
264  }
265  else {
266  /* not much to do since t1 is going to destroy all information
267  in t2, except its range */
269  t1 = transformer_range_intersection(t1, r);
270  free_transformer(r);
271  }
272  }
273  else if(transformer_is_rn_p(t2) && !ENDP(wvl) && arguments_set_equal_p(a2, wvl)) {
274  if(transformer_is_empty_p(t1))
275  //t1 == t1;
276  ;
277  else {
278  /* not much to do since t2 is going to destroy all information
279  in t1, except its domain */
281  free_transformer(t1);
283  free_transformer(d);
284  }
285  }
286  /* Standard case */
287  else {
288  /* Newgen does not generate the proper castings */
289  /* Automatic variables read in a CATCH block need to be declared volatile as
290  * specified by the documentation*/
293  /* ints: list of intermediate value entities */
294  volatile list ints = NIL;
295  list ce2;
296 
297  pips_debug(8,"begin\n");
298 
299  pips_debug(8,"arg. t1=%p\n",t1);
300  ifdebug(8) (void) dump_transformer(t1);
301  /* The consistencies of transformers t1 and t2 cannot be checked with
302  respect to the current environment because t1 or t2 may be relative
303  to a callee as in user_function_call_to_transformer(). Hence a
304  debug level of 10. */
305  ifdebug(10) pips_assert("consistent t1", transformer_consistency_p(t1));
306 
307  pips_debug(8,"arg. t2=%p\n",t2);
308  ifdebug(8) (void) dump_transformer(t2);
309  ifdebug(10) pips_assert("consistent t2", transformer_consistency_p(t2));
310 
311  if(!sc_empty_p(r1)) {
312 
313  if(sc_empty_p(r2)) {
314  empty_transformer(t1);
315  }
316  else { /* both t1 and t2 are not obviously unfeasible */
317 
318  /* build new argument list and rename old and intermediate values,
319  as well as new (i.e. unmodified) variables in t1 */
320 
321  for(ce2 = a2; !ENDP(ce2); POP(ce2)) {
322  entity e2 = ENTITY(CAR(ce2));
323  if(entity_is_argument_p(e2, a1)) {
324  /* renaming of intermediate values in r1 and r2 */
326  entity e_old = entity_to_old_value(e2);
327  r1 = sc_variable_rename(r1, (Variable) e2, (Variable) e_int);
328  r2 = sc_variable_rename(r2, (Variable) e_old, (Variable) e_int);
329  ints = arguments_add_entity(ints, e_int);
330  }
331  else {
332  /* if ever e2 is used as e2#new in r1 it must now be
333  replaced by e2#old */
334  if(base_contains_variable_p(r1->base, (Variable) e2)) {
335  entity e_old = entity_to_old_value(e2);
336  r1 = sc_variable_rename(r1, (Variable) e2, (Variable) e_old);
337  }
338  /* e2 must be appended to a1 as new t1's arguments;
339  hopefully we are not iterating on a1; but
340  entity_is_argument_p() receives a longer argument each time;
341  possible improvements? */
342  a1 = gen_nconc(a1, CONS(ENTITY, e2, NIL));
343  }
344  }
345 
346  /* build global linear system: r1 is destroyed, r2 is preserved
347  */
348  r1 = sc_append(r1, r2);
349 
350  /* ??? The base returned may be empty... FC...
351  * boumbadaboum in the projection later on.
352  */
353  sc_rm(r2);
354  r2 = SC_UNDEFINED;
355  ifdebug(9) {
356  pips_debug(9, "global linear system r1 before projection\n");
357  sc_fprint(stderr, r1, (char * (*)(Variable)) dump_value_name);
358  sc_dump(r1);
359  }
360 
361  /* get rid of intermediate values, if any.
362  * ??? guard added to avoid an obscure bug, but I guess it should
363  * never get here with en nil base... FC
364  */
365  if (sc_base(r1)) {
366  VOLATILE_FOREACH(ENTITY, e_temp, ints)
367  {
368  if (sc_expensive_projection_p(r1,(Variable) e_temp)) {
369  ifdebug(9) {
370  pips_debug(9, "expensive projection on %s with\n",
371  entity_local_name(e_temp));
372  sc_fprint(stderr, r1, (char * (*)(Variable)) entity_local_name);
373  }
374  sc_elim_var(r1,(Variable) e_temp);
375  sc_base_remove_variable(r1,(Variable) e_temp);
376  ifdebug(9) {
377  pips_debug(9, "simplified tranformer\n");
378  sc_fprint(stderr, r1,(char * (*)(Variable)) entity_local_name);
379  }
380  }
381  else {
383  {
384  /* CA */
385  /*PIER: problem with e_temp that should be volatile because of
386  * the catch structure. Not easy make it volatile because of
387  * the MAP MACRO */
388  pips_user_warning("overflow error in projection of %s, "
389  "variable eliminated\n",
390  entity_name(e_temp));
391  r1 = sc_elim_var(r1, (Variable) e_temp);
392  }
393  TRY
394  {
395  sc_and_base_projection_along_variable_ofl_ctrl
396  (&r1, (Variable) e_temp, NO_OFL_CTRL);
398  }
399 
400  if (! sc_empty_p(r1)) {
401  r1 = sc_normalize2(r1);
402  if(SC_EMPTY_P(r1)) {
403  r1 = sc_empty(BASE_NULLE);
404  break;
405  }
406  }
407  }
408  }
409  }
410 
411  ifdebug(9) {
412  pips_debug(9, "global linear system r1 after projection\n");
413  sc_fprint(stderr, r1, (char * (*)(Variable)) dump_value_name);
414  sc_dump(r1);
415  }
416 
417  /* get rid of ints */
418  gen_free_list(ints);
419  ints = NIL;
420 
421  /* update t1 */
422  if(sc_empty_p(r1)) {
423  /* No old values should be left in r1's basis. */
424  MAP(ENTITY, v, {
425  entity oldv = entity_to_old_value(v);
426  if(base_contains_variable_p(sc_base(r1), (Variable) oldv))
427  sc_base_remove_variable(r1, (Variable) oldv);
428  }, a1);
429  free_arguments(a1);
431  }
432  else {
433  transformer_arguments(t1) = a1;
434  }
436  }
437  }
438  }
439 
440  pips_debug(8,"res. t1=%p\n",t1);
441  ifdebug(8) dump_transformer(t1);
442  pips_debug(8,"end\n");
443 
444  return t1;
445 }
bool arguments_set_equal_p(list a1, list a2)
Set equality of lists a1 and a2.
Definition: arguments.c:181
#define CATCH(what)
@ overflow_error
#define UNCATCH(what)
#define TRY
bool transformer_is_rn_p(transformer t)
Check that transformer t is the canonical representation of the whole afine space defined by its basi...
Definition: basic.c:183
transformer empty_transformer(transformer t)
Do not allocate an empty transformer, but transform an allocated transformer into an empty_transforme...
Definition: basic.c:144
bool transformer_is_empty_p(transformer t)
Check that transformer t is the canonical representation of an empty transformer.
Definition: basic.c:172
if(!(yy_init))
Definition: genread_lex.c:1029
#define VOLATILE_FOREACH(_fe_CASTER, _fe_item, _fe_list)
Definition: newgen_list.h:186
char end
Definition: gtk_status.c:82
#define pips_user_warning
Definition: misc-local.h:146
void sc_base_remove_variable(Psysteme sc, Variable v)
Definition: sc.c:239
Psysteme sc_variable_rename(Psysteme s, Variable v_old, Variable v_new)
Psysteme sc_variable_rename(Psysteme s, Variable v_old, Variable v_new): reecriture du systeme s remp...
Definition: sc.c:157
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
Psysteme sc_append(Psysteme s1, Psysteme s2)
Psysteme sc_append(Psysteme s1, Psysteme s2): calcul de l'intersection des polyedres definis par s1 e...
void sc_dump(Psysteme sc)
void sc_dump(Psysteme sc): dump to stderr
Definition: sc_io.c:142
Psysteme sc_normalize2(volatile Psysteme ps)
Psysteme sc_normalize2(Psysteme ps): normalisation d'un systeme d'equation et d'inequations lineaires...
Psysteme sc_elim_var(Psysteme sc, Variable v)
package sur les systemes de contraintes sc
Definition: sc_unaires.c:49
transformer transformer_domain_intersection(transformer tf, transformer pre)
Restrict the domain of the relation tf with pre.
Definition: transformer.c:661
transformer transformer_range_intersection(transformer tf, transformer r)
Allocate a new transformer rtf that is tf with its range restricted by the range r.
Definition: transformer.c:830
transformer transformer_to_domain(transformer tf)
Return the domain of relation tf in a newly allocated transformer.
Definition: transformer.c:772
entity entity_to_intermediate_value(entity)
Definition: value.c:879
list modified_variables_with_values(void)
Return the list of all analyzed variables which are modified in the current module.
Definition: value.c:1094
#define NO_OFL_CTRL

References arguments_add_entity(), arguments_set_equal_p(), Ssysteme::base, base_contains_variable_p(), BASE_NULLE, CAR, CATCH, CONS, copy_transformer(), dump_transformer, dump_value_name(), empty_transformer(), ENDP, ENTITY, entity_is_argument_p(), entity_local_name(), entity_name, entity_to_intermediate_value(), entity_to_old_value(), free_arguments(), free_transformer(), gen_free_list(), gen_nconc(), ifdebug, MAP, modified_variables_with_values(), NIL, NO_OFL_CTRL, overflow_error, pips_assert, pips_debug, pips_user_warning, POP, predicate_system, sc_append(), sc_base_remove_variable(), sc_dump(), sc_dup(), sc_elim_var(), sc_empty(), sc_empty_p(), sc_fprint(), sc_normalize2(), sc_rm(), sc_variable_rename(), transformer_arguments, transformer_consistency_p(), transformer_domain_intersection(), transformer_is_empty_p(), transformer_is_rn_p(), transformer_range(), transformer_range_intersection(), transformer_relation, transformer_to_domain(), TRY, UNCATCH, and VOLATILE_FOREACH.

Referenced by any_assign_operation_to_transformer(), any_assign_to_transformer(), any_conditional_to_transformer(), any_expression_side_effects_to_transformer(), any_expressions_side_effects_to_transformer(), any_expressions_to_transformer(), any_loop_to_k_transformer(), any_scalar_assign_to_transformer_list(), any_scalar_assign_to_transformer_without_effect(), any_transformer_to_k_closure(), any_user_call_site_to_transformer(), assign_rhs_to_reflhs_to_transformer(), assigned_expression_to_transformer(), assigned_expression_to_transformer_list(), block_to_transformer(), block_to_transformer_list(), c_data_to_prec_for_variables(), c_user_call_to_transformer(), c_user_function_call_to_transformer(), combine_transformer_lists(), complete_any_loop_transformer_list(), complete_loop_transformer(), complete_loop_transformer_list(), complete_repeatloop_transformer_list(), condition_to_transformer(), conditional_to_transformer(), dag_or_cycle_to_flow_sensitive_postconditions_or_transformers(), declaration_to_transformer(), declaration_to_transformer_list(), declarations_to_transformer(), declarations_to_transformer_list(), dimensions_to_transformer(), expression_to_transformer(), expressions_to_transformer(), forloop_to_postcondition(), forloop_to_transformer(), fortran_data_to_prec_for_variables(), fortran_user_function_call_to_transformer(), generic_unary_operation_to_transformer(), integer_binary_operation_to_transformer(), integer_expression_to_transformer(), integer_multiply_to_transformer(), loop_to_continue_transformer(), loop_to_postcondition(), loop_to_total_precondition(), loop_to_transformer(), module_name_to_total_preconditions(), modulo_to_transformer(), old_complete_whileloop_transformer(), one_to_one_transformers_combine(), pointer_unary_operation_to_transformer(), propagate_preconditions_in_declarations(), repeatloop_to_transformer(), safe_assigned_expression_to_transformer(), struct_reference_assignment_or_equality_to_transformer(), transformer_add_any_relation_information(), transformer_add_call_condition_information_updown(), transformer_apply(), transformer_apply_field_assignments_or_equalities(), transformer_apply_unknown_field_assignments_or_equalities(), transformer_halbwachs_fix_point(), transformer_inverse_apply(), transformer_list_add_combination(), transformer_safe_combine_with_warnings(), transformers_combine(), whileloop_to_postcondition(), and whileloop_to_total_precondition().

+ Here is the call graph for this function:

◆ transformer_consistency_p()

bool transformer_consistency_p ( transformer  t)

FI: I do not know if this procedure should always return or fail when an inconsistency is found.

For instance, summary transformers for callees are inconsistent with respect to the current module. FC/CA: help...

I do not understand why errors are reported only if the debug level is greater than 1. A demo effect? No, this routine is coded that way to save time on regular runs.

Also, since no precise information about the inconsistency is displayed, a core dump would be welcome to retrieve pieces of information with gdb. The returned value should always be tested and a call to pips_internal_error() should always be performed if an inconsistency is detected.

But, see final comment... In spite of it, I do not always return any longer.

Definition at line 612 of file basic.c.

613 {
614  return transformer_general_consistency_p(t, false);
615 }
bool transformer_general_consistency_p(transformer tf, bool is_weak)
Definition: basic.c:632

References transformer_general_consistency_p().

Referenced by block_to_transformer(), block_to_transformer_list(), call_to_transformer(), declarations_to_transformer(), declarations_to_transformer_list(), generic_module_name_to_transformers(), initial_precondition(), loop_to_total_precondition(), module_name_to_total_preconditions(), move_transformer(), node_to_path_transformer_or_postcondition(), print_cycle_head_to_fixpoint(), program_postcondition(), program_precondition(), propagate_preconditions_in_declarations(), safe_assigned_expression_to_transformer(), statement_to_postcondition(), statement_to_total_precondition(), statement_to_transformer(), statement_to_transformer_list(), store_control_fix_point(), store_control_postcondition(), transformer_add_loop_index_incrementation(), transformer_add_sign_information(), transformer_combine(), transformer_derivative_fix_point(), transformer_internal_consistency_p(), transformer_inverse_apply(), transformer_list_closure_to_precondition(), transformer_list_closure_to_precondition_depth_two(), transformer_list_generic_transitive_closure(), transformer_list_multiple_closure_to_precondition(), transformer_normalize(), unstructured_to_flow_sensitive_postconditions(), and unstructured_to_flow_sensitive_total_preconditions().

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

◆ transformer_constraint_add()

transformer transformer_constraint_add ( transformer  tf,
Pvecteur  i,
bool  equality 
)
Parameters
tff
equalityquality

Definition at line 348 of file basic.c.

352 {
353  Pcontrainte c;
354  Psysteme sc;
355 
356  pips_assert("tf is defined", tf != transformer_undefined
357  && tf != (transformer) NULL);
358 
359  if(VECTEUR_NUL_P(i)) {
360  user_warning("transformer_constraint_add",
361  "trivial constraint 0 %s 0 found: code should be optimized\n",
362  (equality)? "==" : "<=");
363  return tf;
364  }
365 
366  c = contrainte_make(i);
368 
369  sc = sc_constraint_add(sc, c, equality);
370 
371  return tf;
372 }
#define user_warning(fn,...)
Definition: misc-local.h:262
Psysteme sc_constraint_add(Psysteme sc, Pcontrainte c, bool equality)
Definition: sc_insert_eq.c:115

References contrainte_make(), pips_assert, predicate_system, sc_constraint_add(), transformer_relation, transformer_undefined, user_warning, and VECTEUR_NUL_P.

Referenced by transformer_equalities_add(), transformer_equality_add(), transformer_inequalities_add(), and transformer_inequality_add().

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

◆ transformer_convex_hull()

transformer transformer_convex_hull ( transformer  t1,
transformer  t2 
)

convex_hull.c

convex_hull.c

return transformer_convex_hulls(t1, t2, sc_enveloppe);

return transformer_convex_hulls(t1, t2, sc_enveloppe_chernikova);

return transformer_convex_hulls(t1, t2, sc_common_projection_convex_hull);

t1 = transformer_normalize(t1, 4);

t2 = transformer_normalize(t2, 4);

Parameters
t11
t22

Definition at line 216 of file convex_hull.c.

217 {
218  /* return transformer_convex_hulls(t1, t2, sc_enveloppe); */
219  /* return transformer_convex_hulls(t1, t2, sc_enveloppe_chernikova); */
220  /* return transformer_convex_hulls(t1, t2, sc_common_projection_convex_hull);
221  */
222 /* t1 = transformer_normalize(t1, 4); */
223 /* t2 = transformer_normalize(t2, 4); */
224  t1 = transformer_normalize(t1, 2);
225  t2 = transformer_normalize(t2, 2);
227 }
Psysteme cute_convex_union(Psysteme s1, Psysteme s2)
debug messages before calling the version in polyedre.
Definition: convex_hull.c:41
static transformer transformer_convex_hulls(transformer t1, transformer t2, Psysteme(*method)(Psysteme, Psysteme))
temporarily, for ifdebug
Definition: convex_hull.c:57

References cute_convex_union(), transformer_convex_hulls(), and transformer_normalize().

Referenced by add_module_call_site_precondition(), any_assign_to_transformer(), any_basic_update_to_transformer(), any_conditional_to_transformer(), any_loop_to_k_transformer(), any_loop_to_postcondition(), any_transformer_to_k_closure(), any_update_to_transformer(), complete_loop_transformer(), complete_loop_transformer_list(), condition_to_transformer(), conditional_to_transformer(), dag_or_cycle_to_flow_sensitive_postconditions_or_transformers(), dag_to_flow_sensitive_preconditions(), generic_transformer_list_to_transformer(), generic_unary_operation_to_transformer(), get_control_precondition(), lhs_expression_to_transformer(), loop_body_transformer_add_entry_and_iteration_information(), loop_to_postcondition(), loop_to_total_precondition(), main(), new_array_elements_backward_substitution_in_transformer(), new_array_elements_forward_substitution_in_transformer(), old_complete_whileloop_transformer(), points_to_unary_operation_to_transformer(), process_call_for_summary_precondition(), process_ready_node(), repeatloop_to_postcondition(), repeatloop_to_transformer(), statement_to_transformer(), statement_to_transformer_list(), struct_reference_assignment_or_equality_to_transformer(), test_to_postcondition(), test_to_total_precondition(), test_to_transformer(), transformer_add_anded_conditions_updown(), transformer_add_any_relation_information(), transformer_add_integer_relation_information(), transformer_add_ored_conditions_updown(), transformer_halbwachs_fix_point(), transformer_list_closure_to_precondition_depth_two(), transformer_list_closure_to_precondition_max_depth(), unstructured_to_flow_insensitive_transformer(), update_summary_precondition(), update_temporary_precondition(), and whileloop_to_postcondition().

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

◆ transformer_derivative_constraints()

Psysteme transformer_derivative_constraints ( transformer  t)

Allocate a new constraint system sc(dx) with dx=x'-x and t(x,x')

FI: this function should/might be located in fix_point.c

sc is going to be modified and returned

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

basis vector

Compute constraints with difference equations

Only generate difference equations if the old value is used

Project all variables but differences to get T'

Definition at line 891 of file transformer_list.c.

892 {
894  /* sc is going to be modified and returned */
895  /* Do not handle variable which do not appear explicitly in constraints! */
896  Pbase b = sc_to_minimal_basis(sc);
897  Pbase bv = BASE_NULLE; /* basis vector */
898 
899  /* Compute constraints with difference equations */
900 
901  for(bv = b; !BASE_NULLE_P(bv); bv = bv->succ) {
902  entity oldv = (entity) vecteur_var(bv);
903 
904  /* Only generate difference equations if the old value is used */
905  if(old_value_entity_p(oldv)) {
906  entity var = value_to_variable(oldv);
907  entity newv = entity_to_new_value(var);
909  Pvecteur diff = VECTEUR_NUL;
911 
912  diff = vect_make(diff,
913  (Variable) diffv, VALUE_ONE,
914  (Variable) newv, VALUE_MONE,
915  (Variable) oldv, VALUE_ONE,
916  TCST, VALUE_ZERO);
917 
918  eq = contrainte_make(diff);
919  sc = sc_equation_add(sc, eq);
920  }
921  }
922 
923  ifdebug(8) {
924  pips_debug(8, "with difference equations=\n");
925  sc_fprint(stderr, sc, (char * (*)(Variable)) external_value_name);
926  }
927 
928  /* Project all variables but differences to get T' */
929 
930  sc = sc_projection_ofl_along_variables(sc, b);
931 
932  ifdebug(8) {
933  pips_debug(8, "Non-homogeneous constraints on derivatives=\n");
934  sc_fprint(stderr, sc, (char * (*)(Variable)) external_value_name);
935  }
936 
937  return sc;
938 }
Psysteme sc_copy(Psysteme ps)
Psysteme sc_copy(Psysteme ps): duplication d'un systeme (allocation et copie complete des champs sans...
Definition: sc_alloc.c:230
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

References BASE_NULLE, BASE_NULLE_P, contrainte_make(), CONTRAINTE_UNDEFINED, entity_to_intermediate_value(), entity_to_new_value(), eq, external_value_name(), ifdebug, old_value_entity_p(), pips_debug, predicate_system, sc_copy(), sc_equation_add(), sc_fprint(), sc_to_minimal_basis(), Svecteur::succ, TCST, transformer_relation, VALUE_MONE, VALUE_ONE, value_to_variable(), VALUE_ZERO, vect_make(), VECTEUR_NUL, and vecteur_var.

Referenced by transformer_list_generic_transitive_closure().

+ 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!

Parameters
tff

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 }
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
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
entity make_local_temporary_integer_value_entity(void)
Definition: value.c:629
Pbase base_dup(Pbase b)
Pbase base_dup(Pbase b) Note: this function changes the value of the pointer.
Definition: alloc.c:268

Referenced by transformers_derivative_fix_point().

+ Here is the caller graph for this function:

◆ transformer_domain_intersection()

transformer transformer_domain_intersection ( transformer  tf,
transformer  pre 
)

Restrict the domain of the relation tf with pre.

pre is assumed to be restricted to a store predicate: its argument list must be empty.

For a restriction on the image of tf, see transformer_image_intersection

tf is updated by side effect although transformer_image_intersection() allocates a fresh new transformer.

if a value in pre is modified by tf, it must be renamed as an old value

transformer dom is not consistent since it references old values but has no arguments

Parameters
tff
prere

Definition at line 661 of file transformer.c.

663 {
664  transformer dom = transformer_dup(pre);
666 
667  pips_assert("pre does not involve old values and has no arguments",
669 
670  pips_debug(9, "Begin with tf=%p and pre=%p\n", tf, pre);
671 
672  /* if a value in pre is modified by tf, it must be renamed as an old
673  value */
674  MAP(ENTITY, a, {
675  entity na = entity_to_new_value(a);
676  entity oa = entity_to_old_value(a);
678  pre_sc = sc_variable_rename(pre_sc, (Variable) na, (Variable) oa);
679  }, transformer_arguments(tf));
680 
681  /* transformer dom is not consistent since it references old values but
682  has no arguments */
683 
684  tf_inter = transformer_image_intersection(tf, dom);
685  tf = move_transformer(tf, tf_inter);
686  free_transformer(dom);
687 
688  return tf;
689 }
transformer move_transformer(transformer t1, transformer t2)
Move arguments and predicate of t2 into t1, free old arguments and predicate of t1,...
Definition: basic.c:939
transformer transformer_image_intersection(transformer t1, transformer t2)
allocate a new transformer based on transformer t1 and postcondition t2
Definition: transformer.c:608

References ENDP, ENTITY, entity_to_new_value(), entity_to_old_value(), free_transformer(), MAP, move_transformer(), pips_assert, pips_debug, predicate_system, sc_variable_rename(), transformer_arguments, transformer_dup(), transformer_image_intersection(), transformer_relation, and transformer_undefined.

Referenced by loop_body_transformer_add_entry_and_iteration_information(), loop_to_transformer(), statement_to_transformer(), statement_to_transformer_list(), transformer_combine(), and transformer_safe_domain_intersection().

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

◆ transformer_dup()

transformer transformer_dup ( transformer  t_in)

cproto-generated files

basic.c

cproto-generated files

Francois Irigoin

FI: I do not reduce transformer_dup() to a macro calling copy_transformer() because I do not want to create problems with the link edit and because I want to keep the assertion

Parameters
t_in_in

Definition at line 49 of file basic.c.

50 {
51  /* FI: I do not reduce transformer_dup() to a macro calling
52  copy_transformer() because I do not want to create problems with
53  the link edit and because I want to keep the assertion */
54 
55  Psysteme sc = SC_UNDEFINED;
56  transformer t_out;
57 
58  pips_assert("transformer t_in is not undefined", t_in != transformer_undefined);
59 
61  pips_assert("transformer_dup", !SC_UNDEFINED_P(sc));
62  t_out = copy_transformer(t_in);
63 
64  return t_out;
65 }

References copy_transformer(), pips_assert, predicate_system, transformer_relation, and transformer_undefined.

Referenced by add_index_bound_conditions(), add_loop_index_exit_value(), any_transformer_to_k_closure(), block_to_postcondition(), block_to_total_precondition(), block_to_transformer(), call_site_to_module_precondition_text(), call_to_summary_precondition(), check_condition_wrt_precondition(), comp_regions_of_implied_do(), complete_loop_transformer(), complete_loop_transformer_list(), cycle_to_flow_sensitive_preconditions(), dag_to_flow_sensitive_preconditions(), declarations_to_transformer(), declarations_to_transformer_list(), eval_condition_wrt_precondition_p(), forloop_to_postcondition(), fortran_user_call_to_transformer(), generic_module_name_to_transformers(), generic_transformer_intra_to_inter(), integer_expression_and_precondition_to_integer_interval(), interprocedural_abc_arrays(), load_arc_precondition(), loop_to_postcondition(), loop_to_total_precondition(), loop_to_transformer(), module_name_to_total_preconditions(), old_complete_whileloop_transformer(), precondition_to_abstract_store(), process_call_for_summary_precondition(), process_ready_node(), program_precondition(), propagate_preconditions_in_declarations(), recompute_loop_transformer(), standard_whileloop_to_transformer(), test_to_postcondition(), test_to_transformer(), test_to_transformer_list(), transformer_add_anded_conditions_updown(), transformer_add_any_relation_information(), transformer_add_integer_relation_information(), transformer_add_ored_conditions_updown(), transformer_apply(), transformer_convex_hulls(), transformer_derivative_fix_point(), transformer_domain_intersection(), transformer_equality_fix_point(), transformer_halbwachs_fix_point(), transformer_inverse_apply(), transformer_pattern_fix_point(), transformer_range(), transformer_to_domain(), unstructured_continuation_conditions(), unstructured_to_postcondition(), unstructured_to_postconditions(), unstructured_to_total_precondition(), unstructured_to_transformer(), update_summary_precondition(), update_temporary_precondition(), and whileloop_to_postcondition().

+ Here is the call graph for this function:

◆ transformer_empty()

transformer transformer_empty ( void  )

Allocate an empty transformer.

Definition at line 120 of file basic.c.

121 {
122  return make_transformer(NIL,
124 }

References BASE_NULLE, make_predicate(), make_transformer(), NIL, and sc_empty().

Referenced by add_index_range_conditions(), block_continuation_conditions(), call_continuation_conditions(), complete_repeatloop_transformer_list(), dag_or_cycle_to_flow_sensitive_postconditions_or_transformers(), expression_multiply_sizeof_to_transformer(), generic_transformer_list_to_transformer(), get_control_precondition(), integer_binary_operation_to_transformer(), intrinsic_to_transformer(), intrinsic_to_transformer_list(), load_arc_precondition(), loop_continuation_conditions(), loop_to_postcondition(), loop_to_total_precondition(), module_summary_continuation_conditions(), modulo_of_a_constant_to_transformer(), modulo_to_transformer(), new_array_elements_backward_substitution_in_transformer(), new_array_elements_forward_substitution_in_transformer(), new_substitute_stubs_in_transformer(), ordinary_summary_precondition(), pointer_binary_operation_to_transformer(), points_to_unary_operation_to_transformer(), precondition_intra_to_inter(), process_bounds_for_divide(), process_unreachable_node(), ready_to_be_processed_p(), repeatloop_to_postcondition(), standard_whileloop_to_transformer(), statement_to_total_precondition(), summary_total_postcondition(), test_continuation_conditions(), transformer_add_call_condition_information_updown(), transformer_add_condition_information_updown(), transformer_general_intersection(), transformer_list_generic_transitive_closure(), unstructured_continuation_conditions(), unstructured_to_flow_insensitive_transformer(), unstructured_to_postconditions(), unstructured_to_transformer(), whileloop_to_postcondition(), and whileloop_to_total_precondition().

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

◆ transformer_empty_p()

bool transformer_empty_p ( transformer  t)

If true is returned, the transformer certainly is empty.

If false is returned, the transformer still might be empty, but it's not too likely...

Well, k <= 2 and k >= 3 does not return empty in spite of sc_strong_normalize()... sc_bounded_normalization() should be used at a cost of O(n)

See also transformer_is_empty_p() for a simple quick syntactic check

Definition at line 2455 of file transformer.c.

2456 {
2458  return empty_p;
2459 }
Psysteme sc_strong_normalize4(Psysteme ps, char *(*variable_name)(Variable))
Psysteme sc_strong_normalize4(Psysteme ps, char * (*variable_name)(Variable))
static bool parametric_transformer_empty_p(transformer t, Psysteme(*normalize)(Psysteme, char *(*)(Variable)))
If true is returned, the transformer certainly is empty.
Definition: transformer.c:2319

References parametric_transformer_empty_p(), and sc_strong_normalize4().

Referenced by apply_transformer_lists_generic(), block_to_transformer_list(), check_condition_wrt_precondition(), check_transformer_list(), clean_up_transformer_list(), combine_transformer_lists(), eval_condition_wrt_precondition_p(), fortran_user_call_to_transformer(), generic_module_name_to_transformers(), instruction_to_transformer_list(), integer_binary_operation_to_transformer(), integer_multiply_to_transformer(), logical_binary_function_to_transformer(), main_summary_precondition(), precondition_intra_to_inter(), process_unreachable_node(), ready_to_be_processed_p(), simplify_boolean_expression_with_precondition(), standard_whileloop_to_transformer(), statement_feasible_p(), transformer_add_modified_variable_entity(), transformer_add_value_update(), transformer_apply_generic(), transformer_basic_fix_point(), transformer_convex_hulls(), transformer_derivative_fix_point(), transformer_equality_fix_point(), transformer_general_intersection(), transformer_list_add_combination(), transformer_projection_with_redundancy_elimination_and_check(), transformers_combine(), two_transformers_to_list(), unstructured_to_postcondition(), unstructured_to_total_precondition(), and unstructured_to_transformer().

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

◆ transformer_equalities_add()

transformer transformer_equalities_add ( transformer  tf,
Pcontrainte  eqs 
)

please, do not introduce any sharing at the Pcontrainte level you do not know how they have to be chained in diferent transformers; do not introduce any sharing at the Pvecteur level; I'm not sure it's so useful, but think of what would happen if one transformer is renamed...

Parameters
tff
eqsqs

Definition at line 391 of file basic.c.

394 {
395  /* please, do not introduce any sharing at the Pcontrainte level
396  you do not know how they have to be chained in diferent transformers;
397  do not introduce any sharing at the Pvecteur level; I'm not
398  sure it's so useful, but think of what would happen if one transformer
399  is renamed... */
400  for(;eqs!=CONTRAINTE_UNDEFINED; eqs = eqs->succ)
401  (void) transformer_constraint_add(tf,
403  true);
404  return tf;
405 }
transformer transformer_constraint_add(transformer tf, Pvecteur i, bool equality)
Definition: basic.c:348

References CONTRAINTE_UNDEFINED, contrainte_vecteur, Scontrainte::succ, transformer_constraint_add(), and vect_dup().

Referenced by tf_equivalence_equalities_add().

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

◆ transformer_equality_add()

◆ 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

Parameters
tff

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 }
cons * dup_arguments(cons *args)
Definition: arguments.c:225
#define value_uminus(val)
unary operators on values
#define value_zero_p(val)
#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
Variable variable_of_rank()
entity new_value_to_old_value(entity)
Definition: value.c:1710

◆ transformer_equations_constrain_variable_p()

bool transformer_equations_constrain_variable_p ( const  transformer,
const  entity 
)

Is value v used with a non-zero coefficient by the equations of transformer t?

Definition at line 963 of file basic.c.

964 {
967 }
bool sc_equations_constrain_variable_p(Psysteme sc, Variable var)
Definition: sc_misc.c:190

References predicate_system, sc_equations_constrain_variable_p(), and transformer_relation.

+ Here is the call graph for this function:

◆ transformer_filter()

transformer transformer_filter ( transformer  t,
list  args 
)

transformer transformer_filter(transformer t, cons * args): projection of t along the hyperplane defined by entities in args; this generate a projection and not a cylinder based on the projection;

if the relation associated to t is empty, t is not modified although it should have a basis and this basis should be cleaned up. Since no basis is carried in the current implementation of an empty system, this cannot be performed (FI, 7/12/92).

formal argument args is not modified. t is updated by side effect.

Note: this function is almost equal to transformer_projection(); however, entities of args do not all have to appear in t's relation; thus transformer_filter has a larger definition domain than transformer_projection; on transformer_projection's domain, both functions are equal

transformer_projection is useful to get cores when you know all entities in args should appear in the relation.

Automatic variables read in a CATCH block need to be declared volatile as specified by the documentation

sc_fprint(stderr, r, exernal_value_name);

sc_fprint(stderr, r, (char * (*)(Variable)) entity_local_name);

get rid of unwanted values in the relation r and in the basis

Automatic variables read in a CATCH block need to be declared volatile as specified by the documentation

r = sc_projection(r, (Variable) e);

CA

sc_projection_along_variable_ofl_ctrl_timeout_ctrl

sc_projection_along_variable_ofl_ctrl(&r, (Variable) e, OFL_CTRL);

compute new_args

use functions on arguments instead of in-lining ! MAPL(ce, { entity e = ENTITY(CAR(ce)); if((entity) gen_find_eq(e, args)== (entity) chunk_undefined) { – e must be kept if it is not in args – new_args = arguments_add_entity(new_args, e); }}, transformer_arguments(t));

update the relation and the arguments field for t

Is the relation updated by side effect? Yes, in general. No if the system is non feasible

replace the old arguments by the new one

sc_fprint(stderr, r, exernal_value_name);

Parameters
argsrgs

Definition at line 1716 of file transformer.c.

1717 {
1718  cons * new_args = NIL;
1719  /* Automatic variables read in a CATCH block need to be declared volatile as
1720  * specified by the documentation*/
1722 
1723  ifdebug(9) {
1724  pips_debug(9, "Begin for transformer %p\n", t);
1725  /* sc_fprint(stderr, r, exernal_value_name); */
1726  /* sc_fprint(stderr, r, (char * (*)(Variable)) entity_local_name); */
1728  pips_debug(9, "and entities to be projected: ");
1729  dump_arguments(args);
1730  pips_assert("t is weakly consistent", transformer_weak_consistency_p(t));
1731  }
1732 
1733  if(!ENDP(args) && !SC_EMPTY_P(r)) {
1734  /* get rid of unwanted values in the relation r and in the basis */
1735  volatile list cea = list_undefined;
1736 
1737  for(cea=args; !ENDP(cea); POP(cea)) {
1738  /* Automatic variables read in a CATCH block need to be declared volatile as
1739  * specified by the documentation*/
1740  entity volatile e = ENTITY(CAR(cea));
1741  if(base_contains_variable_p(r->base, (Variable) e)) {
1742  /* r = sc_projection(r, (Variable) e); */
1743  /*
1744  sc_projection_along_variable_ofl_ctrl(&r, (Variable) e,
1745  NO_OFL_CTRL); */
1747  {
1748  /* CA */
1749  pips_user_warning("overflow error in projection of %s, "
1750  "variable eliminated\n",
1751  entity_name(e));
1752  r = sc_elim_var(r, (Variable) e);
1753  }
1754  TRY
1755  {
1756  /* sc_projection_along_variable_ofl_ctrl_timeout_ctrl */
1757  sc_projection_along_variable_ofl_ctrl
1758  (&r, (Variable) e, NO_OFL_CTRL);
1760  }
1761  /* sc_projection_along_variable_ofl_ctrl(&r, (Variable) e,
1762  OFL_CTRL);*/
1764  }
1765  r->dimension = vect_size(r->base);
1766 
1767  /* compute new_args */
1768  /* use functions on arguments instead of in-lining !
1769  MAPL(ce, { entity e = ENTITY(CAR(ce));
1770  if((entity) gen_find_eq(e, args)== (entity) chunk_undefined) {
1771  -- e must be kept if it is not in args --
1772  new_args = arguments_add_entity(new_args, e);
1773  }},
1774  transformer_arguments(t));
1775  */
1776  new_args = arguments_difference(transformer_arguments(t), args);
1777 
1778  /* update the relation and the arguments field for t */
1779 
1780  /* Is the relation updated by side effect?
1781  * Yes, in general. No if the system is non feasible
1782  */
1783 
1785 
1786  /* replace the old arguments by the new one */
1788  if(sc_empty_p(r)) {
1789  transformer_arguments(t) = NULL;
1790  gen_free_list(new_args);
1791  }
1792  else
1793  transformer_arguments(t) = new_args;
1794  }
1795 
1796  ifdebug(9) {
1797  pips_debug(9, "Transformer after argument list update\n");
1798  /* sc_fprint(stderr, r, exernal_value_name); */
1800  }
1801 
1802  ifdebug(1) {
1803  pips_assert("After filtering,"
1804  " transformer t is consistent",
1806  }
1807  pips_debug(9, "End for t=%p\n", t);
1808 
1809  return t;
1810 }
void dump_arguments(cons *args)
entity_name is a macro, hence the code replication
Definition: arguments.c:69
cons * arguments_difference(cons *a1, cons *a2)
set difference: a1 - a2 ; similar to set intersection
Definition: arguments.c:233
bool transformer_weak_consistency_p(transformer t)
Interprocedural transformers do not meet all conditions.
Definition: basic.c:626
#define newgen_Psysteme(p)
Definition: effects.h:47
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
string entity_global_name(entity e)
Used instead of the macro to pass as formal argument.
Definition: entity.c:464

References arguments_difference(), Ssysteme::base, base_contains_variable_p(), CAR, CATCH, Ssysteme::dimension, dump_arguments(), ENDP, ENTITY, entity_global_name(), entity_name, fprint_transformer(), free_arguments(), gen_free_list(), ifdebug, list_undefined, newgen_Psysteme, NIL, NO_OFL_CTRL, overflow_error, pips_assert, pips_debug, pips_user_warning, POP, predicate_system, predicate_system_, sc_base_remove_variable(), sc_elim_var(), sc_empty_p(), transformer_arguments, transformer_relation, transformer_weak_consistency_p(), TRY, UNCATCH, and vect_size().

Referenced by c_user_function_call_to_transformer(), fortran_user_call_to_transformer(), fortran_user_function_call_to_transformer(), loop_to_transformer(), statement_to_postcondition(), statement_to_total_precondition(), transformer_variables_filter(), and translate_global_value().

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

◆ transformer_free()

◆ transformer_general_consistency_p()

bool transformer_general_consistency_p ( transformer  tf,
bool  is_weak 
)

the relation should be consistent and any variable corresponding to an old value should appear in the argument list since an old value cannot (should not) be introduced unless the variable is changed and since every changed variable is in the argument list.

Apparently, a variable may appear as an argument but its old value does not have to appear in the basis if it is not required by the constraints. This does not seem very safe to me (FI, 13 Nov. 95)

The NewGen data structure must be fully defined

The predicate must be weakly consistent. Every variable in the constraints must be in the basis (but not the other way round).

If an old value appears in the predicate, the corresponding variable should be an argument of the transformer

test aliasing between arguments and relations high cost testing

FI: the next test is not safe because val can be a global value not recognized in the current context. old_value_entity_p() returns true or FALSE or pips_error.

A general version of this routine is needed... The return value of a function is not recognized as a global value by old_value_entity_p

old_value_entity_p() is likely to core dump on interprocedural transformers and preconditions.

The constant term should not appear in the basis

The constant term should not be an argument

Check that the transformer is compatible with the current value mappings.

This is not always true as you may need to import the summary transformer of a callee. Before translation, this check will most likely fail.

Debugging step which does not return if an incompatibility is found.

Check that every argument has a value. This is not redundant with the printout procedure which uses entity_minimal_name() and not the value mappings.

Values returned by callees may appear in interprocedural transformers

FI: let the user react and print info before core dumping

pips_assert("transformer_consistency_p", consistent);

Parameters
tff
is_weaks_weak

Definition at line 632 of file basic.c.

633 {
634 #define TRANSFORMER_CONSISTENCY_P_DEBUG_LEVEL 0
635  /* the relation should be consistent
636  * and any variable corresponding to an old value
637  * should appear in the argument list since
638  * an old value cannot (should not) be
639  * introduced unless the variable is changed and
640  * since every changed variable is
641  * in the argument list.
642  *
643  * Apparently, a variable may appear as an argument but its old value
644  * does not have to appear in the basis if it is not required by
645  * the constraints. This does not seem very safe to me (FI, 13 Nov. 95)
646  */
648  list args = transformer_arguments(tf);
649  bool consistent = true;
650 
651  /* The NewGen data structure must be fully defined */
653  consistent = transformer_defined_p(tf);
654  else
655  consistent = true;
656  if(!consistent)
658  "transformer tf is not gen_defined\n");
659 
660  /* The predicate must be weakly consistent. Every variable
661  * in the constraints must be in the basis (but not the other
662  * way round).
663  */
664  consistent = consistent && sc_weak_consistent_p(sc);
665  if(!consistent)
667  "sc is not weakly consistent\n");
668 
669  /* If an old value appears in the predicate, the corresponding
670  * variable should be an argument of the transformer
671  */
672  if(consistent) {
673  Pbase b = sc_base(sc);
674  Pbase t = BASE_UNDEFINED;
675 
676  for( t = b; !BASE_UNDEFINED_P(t) && consistent; t = t->succ) {
677  entity val = (entity) vecteur_var(t);
678 
679  /* test aliasing between arguments and relations
680  high cost testing */
681  ifdebug(8) {
682  bool aliasing = false;
683  const char* emn = entity_module_name(val);
684  const char* eln = entity_local_name(val);
685  list lt = args;
686  entity e;
687  for (lt = args; lt && !aliasing ;POP(lt)) {
688  e = ENTITY(CAR(lt));
689  consistent = consistent &&
690  (same_string_p(entity_local_name(e), eln) ?
692  : true);
693  aliasing = aliasing && entities_may_conflict_p(e,val);
694  }
695 
696  if(!consistent)
697  pips_user_warning("different global variable names in "
698  "arguments and basis: \"%s\"\n", eln);
699  if (aliasing)
700  pips_internal_error("aliasing between arguments and basis: \"%s\" ",
701  entity_name(val));
702  }
703 
704  /* FI: the next test is not safe because val can be
705  * a global value not recognized in the current
706  * context. old_value_entity_p() returns true or FALSE
707  * or pips_error.
708  *
709  * A general version of this routine is needed... The
710  * return value of a function is not recognized as a
711  * global value by old_value_entity_p
712  *
713  * old_value_entity_p() is likely to core dump on
714  * interprocedural transformers and preconditions.
715  */
717  && old_value_entity_p(val)) {
718  entity var = value_to_variable(val);
719 
720  consistent = entity_is_argument_p(var, args);
721  if(!consistent) {
722  dump_transformer(tf);
724  "Old value of \"%s\" in sc but not in arguments of transformer tf, %p\n",
725  entity_name(var), tf);
726  }
727  }
728  /* The constant term should not appear in the basis */
729  if(consistent) {
730  consistent = consistent && !term_cst(t);
731  if(!consistent)
733  "TCST in sc basis\n");
734  }
735  }
736  }
737 
738  /* The constant term should not be an argument */
739  if(consistent) {
740  MAP(ENTITY, e, {
741  consistent = consistent && (e != (entity) TCST);
742  }, args);
743  if(!consistent)
745  "transformer_consistency_p", "TCST appears in arguments\n");
746  }
747 
748  /* Check that the transformer is compatible with the current value mappings.
749  *
750  * This is not always true as you may need to import the summary transformer
751  * of a callee. Before translation, this check will most likely fail.
752  *
753  * Debugging step which does not return if an incompatibility is found.
754  */
755 
756  /* Check that every argument has a value.
757  * This is not redundant with the printout procedure which uses
758  * entity_minimal_name() and not the value mappings.
759  */
760  FOREACH(ENTITY, e, args) {
761  /*
762  pips_assert("Argument entity appears in the value mappings",
763  entity_has_values_p(e));
764  */
765  if(!entity_has_values_p(e)) {
766  /* Values returned by callees may appear in interprocedural
767  transformers */
769  && !entity_stub_sink_p(e)
770  && !entity_in_formal_area_p(e)) {
771  pips_user_warning("No value for argument %s in value mappings\n",
772  entity_name(e));
773  if(!is_weak)
774  consistent = false;
775  }
776  }
777  }
778 
779  if(consistent && !is_weak)
780  consistent = transformer_argument_consistency_p(tf);
781 
782  /* FI: let the user react and print info before core dumping */
783  /* pips_assert("transformer_consistency_p", consistent); */
784 
785  return consistent;
786 }
bool transformer_defined_p(transformer p)
Definition: ri.c:2626
bool entity_stub_sink_p(entity e)
test if an entity is a stub sink for a formal parameter e.g.
bool transformer_argument_consistency_p(transformer t)
Definition: basic.c:551
#define TRANSFORMER_CONSISTENCY_P_DEBUG_LEVEL
bool entities_may_conflict_p(entity e1, entity e2)
Check if two entities may conflict.
Definition: conflicts.c:984
#define same_string_p(s1, s2)
#define true
Definition: newgen_types.h:81
bool entity_in_formal_area_p(entity e)
Formal parameters do not use the standard ram storage.
Definition: entity.c:3196
#define storage_return_p(x)
Definition: ri.h:2516
bool sc_weak_consistent_p(Psysteme sc)
check that sc is well defined, that the numbers of equalities and inequalities are consistent with th...
Definition: sc.c:362
#define BASE_UNDEFINED_P(b)
#define term_cst(varval)

References BASE_UNDEFINED, BASE_UNDEFINED_P, CAR, debug(), dump_transformer, entities_may_conflict_p(), ENTITY, entity_has_values_p(), entity_in_formal_area_p(), entity_is_argument_p(), entity_local_name(), entity_module_name(), entity_name, entity_storage, entity_stub_sink_p(), FOREACH, ifdebug, MAP, old_value_entity_p(), pips_debug, pips_internal_error, pips_user_warning, POP, predicate_system, same_string_p, sc_weak_consistent_p(), storage_return_p, Svecteur::succ, TCST, term_cst, transformer_argument_consistency_p(), transformer_arguments, TRANSFORMER_CONSISTENCY_P_DEBUG_LEVEL, transformer_defined_p(), transformer_relation, value_to_variable(), and vecteur_var.

Referenced by transformer_consistency_p(), transformer_weak_consistency_p(), and transformers_consistency_p().

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

◆ transformer_halbwachs_fix_point()

transformer transformer_halbwachs_fix_point ( transformer  tf)

THIS FUNCTION WAS NEVER CORRECT AND HAS NOT BEEN REWRITTEN FOR THE NEW VALUE PACKAGE

simple fix-point for inductive variables: loop bounds are ignored

cons * args = effects_to_arguments(e);

tf1: transformer for one loop iteration

tf2: transformer for two loop iterations

tf12: transformer for one or two loop iterations

tf23: transformer for two or three loop iterations

tf_star: transformer for one, two, three,... loop iterations should be called tf_plus by I do not use the one_trip flag

preserve transformer of loop body s

temporarily commented out

duplicate tf1 because transformer_combine might not be able to use twice the same argument

input/output relation for one or two iteration of the loop

apply one iteration on tf12

fix-point

should be done again based on Chenikova

tf_star = transformer_fix_point(tf12, tf23);

free useless transformers

Parameters
tff

Definition at line 143 of file fix_point.c.

144 {
145  /* THIS FUNCTION WAS NEVER CORRECT AND HAS NOT BEEN REWRITTEN FOR
146  THE NEW VALUE PACKAGE */
147 
148  /* simple fix-point for inductive variables: loop bounds are
149  ignored */
150 
151  /* cons * args = effects_to_arguments(e); */
152  /* tf1: transformer for one loop iteration */
153  transformer tf1;
154  /* tf2: transformer for two loop iterations */
155  transformer tf2;
156  /* tf12: transformer for one or two loop iterations */
157  transformer tf12;
158  /* tf23: transformer for two or three loop iterations */
159  transformer tf23;
160  /* tf_star: transformer for one, two, three,... loop iterations
161  should be called tf_plus by I do not use the one_trip flag */
163 
164  pips_internal_error("not implemented");
165 
166  /* preserve transformer of loop body s */
167  /* temporarily commented out */
168  /*
169  tf1 = transformer_rename(transformer_dup(tf), args);
170  */
171  tf1 = transformer_dup(tf);
172 
173  ifdebug(8) {
174  (void) fprintf(stderr,"%s: %s\n","loop_to_transformer",
175  "tf1 after renaming =");
176  (void) print_transformer(tf1);
177  }
178 
179  ifdebug(8) {
180  (void) fprintf(stderr,"%s: %s\n","loop_to_transformer", "tf1 =");
181  (void) print_transformer(tf1);
182  }
183 
184  /* duplicate tf1 because transformer_combine might not be able
185  to use twice the same argument */
186  tf2 = transformer_dup(tf1);
187  tf2 = transformer_combine(tf2, tf1);
188 
189  ifdebug(8) {
190  (void) fprintf(stderr,"%s: %s\n","loop_to_transformer", "tf2 =");
191  (void) print_transformer(tf2);
192  }
193 
194  /* input/output relation for one or two iteration of the loop */
195  tf12 = transformer_convex_hull(tf1, tf2);
196 
197  ifdebug(8) {
198  (void) fprintf(stderr,"%s: %s\n","loop_to_transformer", "tf12 =");
199  (void) print_transformer(tf12);
200  }
201 
202  /* apply one iteration on tf12 */
203  tf23 = transformer_combine(tf12, tf1);
204 
205  ifdebug(8) {
206  (void) fprintf(stderr,"%s: %s\n","loop_to_transformer", "tf23 =");
207  (void) print_transformer(tf23);
208  }
209 
210  /* fix-point */
211  /* should be done again based on Chenikova */
212  /* tf_star = transformer_fix_point(tf12, tf23); */
213 
214  ifdebug(8) {
215  (void) fprintf(stderr,"%s: %s\n","loop_to_transformer", "tf_star =");
216  (void) print_transformer(tf_star);
217  }
218 
219  /* free useless transformers */
220  transformer_free(tf1);
221  transformer_free(tf2);
222  transformer_free(tf12);
223  transformer_free(tf23);
224 
225  tf = tf_star;
226 
227  return tf;
228 }

References fprintf(), ifdebug, pips_internal_error, print_transformer, transformer_combine(), transformer_convex_hull(), transformer_dup(), transformer_free(), and transformer_undefined.

Referenced by standard_whileloop_to_transformer().

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

◆ transformer_identity()

transformer transformer_identity ( void  )

Allocate an identity transformer.

return make_transformer(NIL, make_predicate(SC_RN));

en fait, on voudrait initialiser a "liste de contraintes vide"

Definition at line 110 of file basic.c.

111 {
112  /* return make_transformer(NIL, make_predicate(SC_RN)); */
113  /* en fait, on voudrait initialiser a "liste de contraintes vide" */
114  return make_transformer(NIL,
117 }

References CONTRAINTE_UNDEFINED, make_predicate(), make_transformer(), NIL, and sc_make().

Referenced by __attribute__(), addition_operation_to_transformer(), any_expression_to_transformer(), any_expressions_to_transformer(), any_user_call_site_to_transformer(), args_to_transformer(), bitwise_xor_to_transformer(), block_continuation_conditions(), block_to_transformer(), c_data_to_prec_for_variables(), c_return_to_transformer(), call_continuation_conditions(), call_to_transformer(), clean_up_transformer_list(), complete_loop_transformer(), complete_loop_transformer_list(), complete_repeatloop_transformer_list(), compute_postcondition(), condition_to_transformer(), constant_to_transformer(), dag_or_cycle_to_flow_sensitive_postconditions_or_transformers(), declaration_to_transformer(), declaration_to_transformer_list(), declarations_to_transformer(), declarations_to_transformer_list(), dimensions_to_transformer(), effects_to_transformer(), expression_multiply_sizeof_to_transformer(), expressions_to_transformer(), forloop_to_transformer(), fortran_data_to_prec_for_variables(), generic_abs_to_transformer(), generic_module_name_to_transformers(), generic_transformer_list_to_transformer(), iabs_to_transformer(), instruction_to_transformer(), integer_binary_operation_to_transformer(), integer_call_expression_to_transformer(), integer_expression_to_transformer(), integer_left_shift_to_transformer(), integer_minmax_to_transformer(), integer_multiply_to_transformer(), integer_power_to_transformer(), interprocedural_abc_arrays(), intrinsic_to_transformer(), load_completed_statement_transformer(), logical_binary_function_to_transformer(), logical_expression_to_transformer(), loop_continuation_conditions(), loop_to_continue_transformer(), loop_to_enter_transformer(), merge_transformer_lists(), module_name_to_total_preconditions(), module_summary_continuation_conditions(), modulo_by_a_constant_to_transformer(), modulo_of_a_constant_to_transformer(), modulo_of_a_negative_value_to_transformer(), modulo_of_a_positive_value_to_transformer(), modulo_to_transformer(), new_complete_whileloop_transformer_list(), new_whileloop_to_k_transformer(), new_whileloop_to_transformer(), old_complete_whileloop_transformer(), old_summary_precondition(), ordinary_summary_precondition(), pointer_unary_operation_to_transformer(), precondition_intra_to_inter(), program_postcondition(), program_precondition(), repeatloop_to_postcondition(), repeatloop_to_transformer(), safe_any_assign_operation_to_transformer(), safe_any_expression_to_transformer(), safe_assigned_expression_to_transformer(), safe_assigned_expression_to_transformer_list(), safe_expression_to_transformer(), sequence_dg(), standard_whileloop_to_transformer(), statement_continuation_conditions(), statement_to_transformer(), statement_to_transformer_list(), summary_total_postcondition(), test_continuation_conditions(), test_to_transformer(), test_to_transformer_list(), transformer_add_any_relation_information(), transformer_apply_field_assignments_or_equalities(), transformer_apply_unknown_field_assignments_or_equalities(), transformer_convex_hulls(), transformer_derivative_fix_point(), transformer_equality_fix_point(), transformer_general_intersection(), transformer_list_generic_transitive_closure(), transformer_safe_domain_intersection(), translate_to_module_frame(), unstructured_continuation_conditions(), unstructured_to_transformer(), and whileloop_to_postcondition().

+ Here is the call graph for this function:

◆ transformer_identity_p()

bool transformer_identity_p ( transformer  t)

Check that t is an identity function.

no variables are modified; no constraints exist on their values

Definition at line 154 of file basic.c.

155 {
156  /* no variables are modified; no constraints exist on their values */
157 
158  Psysteme s;
159 
160  pips_assert("transformer_identity_p", t != transformer_undefined);
162  return transformer_arguments(t) == NIL && sc_nbre_egalites(s) == 0
163  && sc_nbre_inegalites(s) == 0;
164 }

References NIL, pips_assert, predicate_system, transformer_arguments, transformer_relation, and transformer_undefined.

Referenced by add_module_call_site_precondition(), check_transformer_list(), clean_up_transformer_list(), merge_transformer_lists(), modulo_to_transformer(), process_call_for_summary_precondition(), and two_transformers_to_list().

+ Here is the caller graph for this function:

◆ transformer_image_intersection()

transformer transformer_image_intersection ( transformer  t1,
transformer  t2 
)

allocate a new transformer based on transformer t1 and postcondition t2

Parameters
t11
t22

Definition at line 608 of file transformer.c.

609 {
611 
612  pips_debug(9, "begins with t1 = %p and t2 = %p\n", t1, t2);
613 
614  t = transformer_general_intersection(t1, t2, true);
615 
616  pips_debug(9, "ends with t = %p, t1 = %p and t2 = %p\n", t, t1, t2);
617 
618  return t;
619 }
static transformer transformer_general_intersection(transformer t1, transformer t2, bool image_only)
Allocate a new transformer with constraints in t1 and t2.
Definition: transformer.c:539

References pips_debug, transformer_general_intersection(), and transformer_undefined.

Referenced by statement_to_transformer(), transformer_domain_intersection(), and transformer_range_intersection().

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

◆ transformer_inequalities_add()

transformer transformer_inequalities_add ( transformer  tf,
Pcontrainte  ineqs 
)

Warning:

Parameters
tff
ineqsneqs

Definition at line 409 of file basic.c.

410 {
412 
413  for(ineq = ineqs; !CONTRAINTE_UNDEFINED_P(ineq); ineq = contrainte_succ(ineq))
414  (void) transformer_constraint_add(tf,
415  contrainte_vecteur(ineq),
416  false);
417  return tf;
418 }

References contrainte_succ, CONTRAINTE_UNDEFINED, CONTRAINTE_UNDEFINED_P, contrainte_vecteur, and transformer_constraint_add().

Referenced by generic_minmax_to_transformer().

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

◆ transformer_inequalities_constrain_variable_p()

bool transformer_inequalities_constrain_variable_p ( const  transformer,
const  entity 
)

Is value v used with a non-zero coefficient by the inequalities of transformer t?

Definition at line 972 of file basic.c.

973 {
976 }
bool sc_inequalities_constrain_variable_p(Psysteme sc, Variable var)
Definition: sc_misc.c:195

References predicate_system, sc_inequalities_constrain_variable_p(), and transformer_relation.

+ Here is the call graph for this function:

◆ transformer_inequality_add()

◆ transformer_internal_consistency_p()

bool transformer_internal_consistency_p ( transformer  t)

Same as above but equivalenced variables should not appear in the argument list or in the predicate basis.

Definition at line 790 of file basic.c.

791 {
793  Pbase b = sc_base(sc);
794  Pbase e = BASE_UNDEFINED;
795  list args = transformer_arguments(t);
796  bool consistent = transformer_consistency_p(t);
797 
798  FOREACH(ENTITY, e, args) {
800 
801  if(v!=e) {
802  pips_user_warning("New value %s should be the same entity as variable %s"
803  " as long as equivalence equations are not added\n",
805  pips_assert("Argument must be a value", false);
806  }
807  }
808 
809  for(e=b; !BASE_NULLE_P(e); e = vecteur_succ(e)) {
810  entity val = (entity) vecteur_var(e);
811 
812  if(!(new_value_entity_p(val) || old_value_entity_p(val)
813  || intermediate_value_entity_p(val))) {
814  // Don't we need something else for sizeof variables ?
815  if(!entity_constant_p(val) && !entity_symbolic_p(val)
816  && !entity_null_locations_p(val)) {
817  pips_user_warning("Variable %s in basis should be an internal value",
818  entity_local_name(val));
819  pips_assert("Basis variables must be an internal value", false);
820  }
821  }
822  }
823 
824  return consistent;
825 }
bool entity_null_locations_p(entity e)
test if an entity is the NULL POINTER
bool intermediate_value_entity_p(entity)
Definition: value.c:955

References BASE_NULLE_P, BASE_UNDEFINED, ENTITY, entity_constant_p, entity_local_name(), entity_null_locations_p(), entity_symbolic_p, entity_to_new_value(), FOREACH, intermediate_value_entity_p(), new_value_entity_p(), old_value_entity_p(), pips_assert, pips_user_warning, predicate_system, transformer_arguments, transformer_consistency_p(), transformer_relation, vecteur_succ, and vecteur_var.

Referenced by recompute_loop_transformer(), statement_to_transformer(), statement_to_transformer_list(), transformer_add_integer_relation_information(), and unstructured_to_flow_insensitive_transformer().

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

◆ transformer_intersect_range_with_domain()

transformer transformer_intersect_range_with_domain ( transformer  tf)

When tf is used repeatedly in a loop, the range is part of the domain from iteration 2 to the end.

This improves the derivative of tf when tf is involutive on a subspace. A new transformer is allocated. Of course, it cannot be used without caution. note that tf must be a range, i.e. no arguments, no old values in the basis.

Parameters
tff

Definition at line 845 of file transformer.c.

846 {
848  transformer ntf = copy_transformer(tf);
851  Pbase b = sc_base(scr);
852  list vl = base_to_entities(b);
853 
854  // No convenient iterator on the basis, hence the temporary list of values
855  FOREACH(ENTITY, v, vl) {
856  entity ov = entity_to_old_value(v);
857 
858  r = transformer_value_substitute(r, v, ov);
859  }
860 
862  // let's hope sc_append takes care of the consistency of sc
863  sc = sc_append(sc, scr);
864 
865  gen_free_list(vl);
866 
867  return ntf;
868 }
list base_to_entities(Pvecteur b)
generate a Newgen list with all entities refered in vector b
Definition: arguments.c:250
transformer transformer_value_substitute(transformer t, entity e1, entity e2)
transformer transformer_value_substitute(transformer t, entity e1, entity e2): if e2 does not appear ...
Definition: transformer.c:1993

References base_to_entities(), copy_transformer(), ENTITY, entity_to_old_value(), FOREACH, gen_free_list(), predicate_system, sc_append(), transformer_range(), transformer_relation, and transformer_value_substitute().

Referenced by any_transformer_to_k_closure().

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

◆ transformer_intersection()

transformer transformer_intersection ( transformer  t1,
transformer  t2 
)

tf is a new transformer that receives the constraints in t1 and t2.

For implicit equalities carried by args, this implies that the args for tf is the intersection of the args. And that the resulting transformer may be empty: for instance, a variable may be untouched in t1 and incremented in t2, which is impossible.

Parameters
t11
t22

Definition at line 600 of file transformer.c.

601 {
603  return t;
604 }

References transformer_general_intersection().

Referenced by bitwise_xor_to_transformer(), expression_multiply_sizeof_to_transformer(), generic_reference_to_transformer(), integer_multiply_to_transformer(), logical_expression_to_transformer(), loop_to_enter_transformer(), pointer_expression_to_transformer(), pointer_unary_operation_to_transformer(), transformer_list_multiple_closure_to_precondition(), and whileloop_to_postcondition().

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

◆ transformer_inverse_apply()

transformer transformer_inverse_apply ( transformer  tf,
transformer  post 
)

transformer transformer_inverse_apply(transformer tf, transformer post): apply transformer tf on precondition pre to obtain postcondition post

pre = post(tf) = tf o post

There is (should be!) no sharing between post and tf. No sharing is introduced between post or tf and pre. Neither post nor tf are modified.

pre = post o tf ; tf would be modified by transformer_combine

Parameters
tff
postost

Definition at line 1657 of file transformer.c.

1658 {
1660  transformer copy_tf = transformer_dup(tf);
1661 
1662  pips_debug(8,"begin with\n");
1663  pips_assert("tf is not undefined", tf!=transformer_undefined);
1664  pips_debug(8,"tf=%p\n", tf);
1665  ifdebug(8) (void) dump_transformer(tf);
1666  pips_assert("post is not undefined", post!=transformer_undefined);
1667  pips_debug(8,"post=%p\n", post);
1668  ifdebug(8) {
1669  (void) dump_transformer(post);
1670  pips_assert("tf is consistent", transformer_consistency_p(tf));
1671  pips_assert("post is consistent", transformer_consistency_p(post));
1672  }
1673 
1674  /* pre = post o tf ; tf would be modified by transformer_combine */
1675  pre = transformer_combine(copy_tf, post);
1676 
1677  pips_assert("pre is not undefined", pre!=transformer_undefined);
1678  pips_debug(8,"return: pre=%p\n", pre);
1679  ifdebug(8) (void) dump_transformer(pre);
1680  pips_assert("unexpected sharing",post != pre);
1681  pips_debug(8,"end\n");
1682 
1683  return pre;
1684 }

References dump_transformer, ifdebug, pips_assert, pips_debug, transformer_combine(), transformer_consistency_p(), transformer_dup(), and transformer_undefined.

Referenced by call_to_total_precondition(), loop_to_total_precondition(), and transformer_safe_inverse_apply().

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

◆ transformer_is_empty_p()

bool transformer_is_empty_p ( transformer  t)

Check that transformer t is the canonical representation of an empty transformer.

See transformer_empty_p(), transformer_strongly_empty_p() if you need to check that a set of affine constraints is not feasible.

Definition at line 172 of file basic.c.

173 {
174  Psysteme s;
175 
176  pips_assert("transformer_identity_p", t != transformer_undefined);
178  return sc_empty_p(s) && ENDP(transformer_arguments(t));
179 }

References ENDP, pips_assert, predicate_system, sc_empty_p(), transformer_arguments, transformer_relation, and transformer_undefined.

Referenced by generic_apply_effects_to_transformer(), transformer_combine(), and transformer_normalize().

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

◆ transformer_is_rn_p()

bool transformer_is_rn_p ( transformer  t)

Check that transformer t is the canonical representation of the whole afine space defined by its basis.

Definition at line 183 of file basic.c.

184 {
185  Psysteme s;
186 
187  pips_assert("transformer_identity_p", t != transformer_undefined);
189  return sc_nbre_egalites(s)==0 && sc_nbre_inegalites(s)==0;
190 }

References pips_assert, predicate_system, transformer_relation, and transformer_undefined.

Referenced by eval_linear_expression(), and transformer_combine().

+ Here is the caller graph for this function:

◆ transformer_list_closure_to_precondition()

transformer transformer_list_closure_to_precondition ( list  tl,
transformer  c_t,
transformer  p_0 
)

Relay to select a heuristic.

Parameters
tll
c_t_t
p_0_0

Definition at line 705 of file transformer_list.c.

708 {
710  const char* h = get_string_property("SEMANTICS_LIST_FIX_POINT_OPERATOR");
711 
712  if(strcmp(h, "depth_two")) {
714  }
715  else if(strcmp(h, "max_depth")) {
717  }
718  else
719  pips_user_error("Unknown value \"%s\" for property "
720  "\"SEMANTICS_LIST_FIX_POINT_OPERATOR\"", h);
721  pips_assert("prec is consistent", transformer_consistency_p(p_star));
722  return p_star;
723 }
char * get_string_property(const char *)
#define pips_user_error
Definition: misc-local.h:147
static transformer transformer_list_closure_to_precondition_max_depth(list tl, transformer c_t, transformer p_0)
Compute the precondition of a loop whose body transformers T_i are in transformer list tl and whose c...
static transformer transformer_list_closure_to_precondition_depth_two(list tl, transformer c_t, transformer p_0)
Compute the precondition of a loop whose body transformers T_i are in transformer list tl and whose c...

References get_string_property(), pips_assert, pips_user_error, transformer_consistency_p(), transformer_list_closure_to_precondition_depth_two(), transformer_list_closure_to_precondition_max_depth(), and transformer_undefined.

Referenced by transformer_list_multiple_closure_to_precondition().

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

◆ transformer_list_generic_transitive_closure()

transformer transformer_list_generic_transitive_closure ( list  tfl,
bool  star_p 
)

Computation of an upper approximation of a transitive closure using constraints on the discrete derivative for a list of transformers.

Each transformer is used to compute its derivative and the derivatives are unioned by convex hull.

The reason for doing this is D(T1) U D(T2) == D(T1 U T2) but the complexity is lower

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

Implicit equations, n::new - n::old = 0, are added because they are necessary for the convex hull.

Intermediate values are used to encode the differences. For instance, i::int = i::new - i::old This code was cut-and-pasted from transformer_derivative_fix_point() but is more general and subsume it transformer transformer_derivative_fix_point(transformer tf)

Since we compute the * transitive closure and not the + transitive closure, the fix point is the identity.

basis of difference vectors

Compute the global argument list and the global base b

Cannot use arguments_union() because a new list is allocated

For each transformer t in list tl

compute its derivative constraint system

add the equations for the unchanged variables

compute its convex hull with the current value of sc if sc is already defined

Add corresponding equation

This could be optimized by using the convex hull of a Psystemes list and by keeping the dual representation of the result instead of converting it several time back and forth.

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 tc_tf

That's all!

Parameters
tflfl
star_ptar_p

Definition at line 960 of file transformer_list.c.

961 {
963 
964  ifdebug(8) {
965  pips_debug(8, "Begin for transformer list %p:\n", tfl);
966  print_transformers(tfl);
967  }
968 
969  if(ENDP(tfl)) {
970  if(star_p) {
971  /* Since we compute the * transitive closure and not the +
972  transitive closure, the fix point is the identity. */
973  tc_tf = transformer_identity();
974  }
975  else {
976  tc_tf = transformer_empty();
977  }
978  }
979  else {
980  // Pbase ib = base_dup(sc_base(sc)); /* initial and final basis */
981  Pbase ib = BASE_NULLE;
982  Pbase diffb = BASE_NULLE; /* basis of difference vectors */
983  Pbase bv = BASE_NULLE;
984  Pbase b = BASE_NULLE;
985 
986  /* Compute the global argument list and the global base b */
987  list gal = NIL;
988  FOREACH(TRANSFORMER, t, tfl) {
989  list al = transformer_arguments(t);
990  /* Cannot use arguments_union() because a new list is allocated */
991  FOREACH(ENTITY, e, al)
992  gal = arguments_add_entity(gal, e);
993 
994  // FI: this copy is almost entirely memory leaked
996  // redundant with call to transformer_derivative_constraints(t)
997  Pbase tb = sc_to_minimal_basis(sc);
998  Pbase nb = base_union(b, tb);
999  base_rm(b); // base_union() allocates a new base
1000  b = nb;
1001  }
1002 
1003  /* For each transformer t in list tl
1004  *
1005  * compute its derivative constraint system
1006  *
1007  * add the equations for the unchanged variables
1008  *
1009  * compute its convex hull with the current value of sc if sc is
1010  * already defined
1011  */
1012  Psysteme sc = SC_UNDEFINED;
1013  FOREACH(TRANSFORMER, t, tfl) {
1015  FOREACH(ENTITY,e,gal) {
1017  /* Add corresponding equation */
1019  Pvecteur diff = VECTEUR_NUL;
1021 
1022  diff = vect_make(diff,
1023  (Variable) diffv, VALUE_ONE,
1024  TCST, VALUE_ZERO);
1025 
1026  eq = contrainte_make(diff);
1027  tsc = sc_equation_add(tsc, eq);
1028  }
1029  }
1030  if(SC_UNDEFINED_P(sc))
1031  sc = tsc;
1032  else {
1033  /* This could be optimized by using the convex hull of a
1034  Psystemes list and by keeping the dual representation of
1035  the result instead of converting it several time back
1036  and forth. */
1037  Psysteme nsc = cute_convex_union(sc, tsc);
1038  sc_free(sc);
1039  sc = nsc;
1040  }
1041  }
1042 
1043  /* Multiply the constant terms by the iteration number ik and add a
1044  positivity constraint for the iteration number ik and then
1045  eliminate the iteration number ik to get T*(dx). */
1047  //Psysteme sc_t_prime_k = sc_dup(sc);
1048  //sc_t_prime_k = sc_multiply_constant_terms(sc_t_prime_k, (Variable) ik);
1049  sc = sc_multiply_constant_terms(sc, (Variable) ik, star_p);
1050  //Psysteme sc_t_prime_star = sc_projection_ofl(sc_t_prime_k, (Variable) ik);
1051  sc = sc_projection_ofl(sc, (Variable) ik);
1052  if(SC_EMPTY_P(sc)) {
1053  sc = sc_empty(BASE_NULLE);
1054  }
1055  else {
1056  sc->base = base_remove_variable(sc->base, (Variable) ik);
1057  sc->dimension--;
1058  // FI: I do not remember nor find how to get rid of local values...
1059  //sc_rm(sc);
1060  //sc = sc_t_prime_star;
1061  }
1062 
1063  ifdebug(8) {
1064  pips_debug(8, "All invariants on derivatives=\n");
1065  sc_fprint(stderr, sc, (char * (*)(Variable)) external_value_name);
1066  }
1067 
1068  /* Difference variables must substituted back to differences
1069  * between old and new values.
1070  */
1071 
1072  for(bv = b; !BASE_NULLE_P(bv); bv = bv->succ) {
1073  entity oldv = (entity) vecteur_var(bv);
1074 
1075  /* Only generate difference equations if the old value is used */
1076  if(old_value_entity_p(oldv)) {
1077  entity var = value_to_variable(oldv);
1078  entity newv = entity_to_new_value(var);
1079  entity diffv = entity_to_intermediate_value(var);
1080  Pvecteur diff = VECTEUR_NUL;
1082 
1083  diff = vect_make(diff,
1084  (Variable) diffv, VALUE_ONE,
1085  (Variable) newv, VALUE_MONE,
1086  (Variable) oldv, VALUE_ONE,
1087  TCST, VALUE_ZERO);
1088 
1089  eq = contrainte_make(diff);
1090  sc = sc_equation_add(sc, eq);
1091  diffb = base_add_variable(diffb, (Variable) diffv);
1092  ib = base_add_variable(ib, (Variable) oldv);
1093  ib = base_add_variable(ib, (Variable) newv);
1094  }
1095  }
1096 
1097  ifdebug(8) {
1098  pips_debug(8,
1099  "All invariants on derivatives with difference variables=\n");
1100  sc_fprint(stderr, sc, (char * (*)(Variable)) external_value_name);
1101  }
1102 
1103  /* Project all difference variables */
1104 
1105  sc = sc_projection_ofl_along_variables(sc, diffb);
1106 
1107  ifdebug(8) {
1108  pips_debug(8, "All invariants on differences=\n");
1109  sc_fprint(stderr, sc, (char * (*)(Variable)) external_value_name);
1110  }
1111 
1112  /* The full basis must be used again */
1113  base_rm(sc_base(sc)), sc_base(sc) = BASE_NULLE;
1114  sc_base(sc) = ib;
1115  sc_dimension(sc) = vect_size(ib);
1116  base_rm(b), b = BASE_NULLE;
1117 
1118  ifdebug(8) {
1119  pips_debug(8, "All invariants with proper basis =\n");
1120  sc_fprint(stderr, sc, (char * (*)(Variable)) external_value_name);
1121  }
1122 
1123  /* Plug sc back into tc_tf */
1125  transformer_arguments(tc_tf) = gal;
1126 
1127  }
1128  /* That's all! */
1129 
1130  ifdebug(8) {
1131  pips_debug(8, "Transitive closure tc_tf=\n");
1134  pips_debug(8, "end\n");
1135  }
1136 
1137  return tc_tf;
1138 }
list print_transformers(list tl)
Definition: io.c:62
Psysteme sc_free(Psysteme in_ps)
Psysteme sc_free( in_ps ) AL 30/05/94 Free of in_ps.
Definition: sc_list.c:112
Psysteme transformer_derivative_constraints(transformer t)
Allocate a new constraint system sc(dx) with dx=x'-x and t(x,x')

References arguments_add_entity(), Ssysteme::base, base_add_variable(), BASE_NULLE, BASE_NULLE_P, base_remove_variable(), base_rm, base_union(), contrainte_make(), CONTRAINTE_UNDEFINED, cute_convex_union(), Ssysteme::dimension, ENDP, ENTITY, entity_is_argument_p(), entity_to_intermediate_value(), entity_to_new_value(), eq, external_value_name(), FOREACH, fprint_transformer(), ifdebug, make_local_temporary_integer_value_entity(), NIL, old_value_entity_p(), pips_debug, predicate_system, print_transformers(), sc_copy(), sc_empty(), sc_equation_add(), sc_fprint(), sc_free(), sc_multiply_constant_terms(), sc_to_minimal_basis(), Svecteur::succ, TCST, TRANSFORMER, transformer_arguments, transformer_consistency_p(), transformer_derivative_constraints(), transformer_empty(), transformer_identity(), transformer_relation, VALUE_MONE, VALUE_ONE, value_to_variable(), VALUE_ZERO, vect_make(), vect_size(), VECTEUR_NUL, and vecteur_var.

Referenced by transformer_list_transitive_closure(), and transformer_list_transitive_closure_plus().

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

◆ transformer_list_multiple_closure_to_precondition()

transformer transformer_list_multiple_closure_to_precondition ( list  tl,
transformer  c_t,
transformer  p_0 
)

When some variables are not modified by some transformers, use projections on subsets to increase the number of identity transformers and to increase the accuracy of the loop precondition.

The preconditions obtained with the different projections are intersected.

FI: this may be useless when derivatives are computed before the convex union. No. This was due to a bug in the computation of list of derivatives.

FI: this should be mathematically useless but it useful when a heuristic is used to compute the invariant. The number of transitions is reduced and hence a limited number of combinations is more likely to end up with a precise result.

Parameters
tll
c_t_t
p_0_0

Definition at line 826 of file transformer_list.c.

829 {
831 
832  if(get_bool_property("SEMANTICS_USE_LIST_PROJECTION")) {
833  list al = transformer_arguments(prec);
834  list vl = transformer_list_to_argument(tl); // list of modified
835  // variables
836  // FI: this is too strong vl must only be included in transformer_arguments(prec)
837  //pips_assert("all modified variables are argument of the global precondition",
838  //arguments_equal_p(vl, transformer_arguments(prec)));
839  FOREACH(ENTITY, v, vl) {
840  // FI: the same projection could be obtained for different
841  // variables v and the computation should not be performed again
842  // but I choose not to memoize past lists tl_v
843  list tl_v = transformer_list_with_effect(tl, v);
844 
845  if(gen_length(tl_v)<gen_length(tl)) {
846  list keep_v = transformer_list_preserved_variables(vl, tl, tl_v);
847  list proj_v = arguments_difference(vl, keep_v);
848  list ptl_v = transformer_list_safe_variables_projection(tl_v, proj_v);
849  transformer p_0_v
851  transformer c_t_v
853  transformer prec_v
854  = transformer_list_closure_to_precondition(ptl_v, c_t_v, p_0_v);
855  if(arguments_subset_p(transformer_arguments(prec_v), al)) {
856  // FI: this generates an inconsistent transformer if
857  // transformer_arguments(prec_v) is not a subset of al...
858  transformer_arguments(prec_v) = gen_copy_seq(al); // memory leak
859  }
860  else {
861  transformer n_prec_v = transformer_range(prec_v);
862  free_transformer(prec_v);
863  prec_v = n_prec_v;
864  transformer_arguments(prec_v) = gen_copy_seq(al);
865  }
866  prec = transformer_intersection(prec, prec_v); // memory leak
867  // transformer_intersection() returns an inconsistent transformer
868  // The argument list is empty but an old value is used in the conditions
869  // prec = transformer_range(prec); // memory leak
870  pips_assert("prec is consistent", transformer_consistent_p(prec));
871 
872  free_transformer(prec_v);
873  free_transformer(c_t_v);
874  free_transformer(p_0_v);
875  gen_full_free_list(ptl_v);
876  gen_free_list(keep_v);
877  }
878  gen_free_list(tl_v);
879  }
880 
881  gen_free_list(vl);
882  }
883  pips_assert("prec is consistent", transformer_consistency_p(prec));
884  return prec;
885 }
bool transformer_consistent_p(transformer p)
Definition: ri.c:2622
bool arguments_subset_p(list a1, list a2)
Check if a1 is a subset of a2.
Definition: arguments.c:204
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
transformer safe_transformer_projection(transformer t, list args)
t may be undefined, args may contain values unrelated to t
Definition: transformer.c:1187
transformer transformer_intersection(transformer t1, transformer t2)
tf is a new transformer that receives the constraints in t1 and t2.
Definition: transformer.c:600
list transformer_list_with_effect(list tl, entity v)
build a sublist sl of the transformer list tl with transformers that modify the value of variable v
transformer transformer_list_closure_to_precondition(list tl, transformer c_t, transformer p_0)
Relay to select a heuristic.
list transformer_list_to_argument(list tl)
Returns the list of variables modified by at least one transformer in tl.
list transformer_list_preserved_variables(list vl, list tl, list tl_v)
returns the list of variables in vl which are not modified by transformers belonging to tl-tl_v.
list transformer_list_safe_variables_projection(list tl, list proj)
Returns a new list of newly allocated projected transformers.

References arguments_difference(), arguments_subset_p(), copy_transformer(), ENTITY, FOREACH, free_transformer(), gen_copy_seq(), gen_free_list(), gen_full_free_list(), gen_length(), get_bool_property(), pips_assert, safe_transformer_projection(), transformer_arguments, transformer_consistency_p(), transformer_consistent_p(), transformer_intersection(), transformer_list_closure_to_precondition(), transformer_list_preserved_variables(), transformer_list_safe_variables_projection(), transformer_list_to_argument(), transformer_list_with_effect(), and transformer_range().

Referenced by whileloop_to_postcondition().

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

◆ transformer_list_preserved_variables()

list transformer_list_preserved_variables ( list  vl,
list  tl,
list  tl_v 
)

returns the list of variables in vl which are not modified by transformers belonging to tl-tl_v.

tl_v is assumed to be a subset of tl.

Parameters
vll
tll
tl_vl_v

Definition at line 786 of file transformer_list.c.

787 {
788  list pvl = NIL;
789 
790  FOREACH(ENTITY, v, vl) {
791  bool found_p = false;
792  FOREACH(TRANSFORMER, t, tl) {
793  if(!gen_in_list_p(t, tl_v)) {
795  found_p = true;
796  break;
797  }
798  }
799  }
800  if(!found_p) {
801  pvl = CONS(ENTITY, v, pvl);
802  }
803  }
804 
805  pvl = gen_nreverse(pvl);
806 
807  return pvl;
808 }
bool gen_in_list_p(const void *vo, const list lx)
tell whether vo belongs to lx
Definition: list.c:734

References CONS, ENTITY, entity_is_argument_p(), FOREACH, gen_in_list_p(), gen_nreverse(), NIL, TRANSFORMER, and transformer_arguments.

Referenced by transformer_list_multiple_closure_to_precondition().

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

◆ transformer_list_safe_variables_projection()

list transformer_list_safe_variables_projection ( list  tl,
list  proj 
)

Returns a new list of newly allocated projected transformers.

If a value of a variable in list proj appears in t of tl, it is projected. New transformers are allocated to build the projection list.

Parameters
tll
projroj

Definition at line 730 of file transformer_list.c.

731 {
732  list ptl = NIL;
733  FOREACH(TRANSFORMER, t, tl) {
734  list apl = NIL; // actual projection list
736  FOREACH(ENTITY, v, proj) {
738  entity ov = entity_to_old_value(v);
739  apl = CONS(ENTITY, ov, apl);
740  }
741  apl = CONS(ENTITY, v, apl);
742  }
743  nt = safe_transformer_projection(nt, apl);
744  ptl = CONS(TRANSFORMER, nt, ptl);
745  gen_free_list(apl);
746  }
747  ptl = gen_nreverse(ptl);
748  return ptl;
749 }

References CONS, copy_transformer(), ENTITY, entity_is_argument_p(), entity_to_old_value(), FOREACH, gen_free_list(), gen_nreverse(), NIL, safe_transformer_projection(), TRANSFORMER, and transformer_arguments.

Referenced by transformer_list_multiple_closure_to_precondition().

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

◆ transformer_list_to_active_transformer_list()

list transformer_list_to_active_transformer_list ( list  tl)
Parameters
tll

Definition at line 454 of file transformer_list.c.

455 {
456  list atl = NIL;
457 
458  FOREACH(TRANSFORMER, tf, tl) {
459  if(!ENDP(transformer_arguments(tf)))
460  atl = CONS(TRANSFORMER, copy_transformer(tf), atl);
461  }
462 
463  atl = gen_nreverse(atl);
464 
465  return atl;
466 }

References CONS, copy_transformer(), ENDP, FOREACH, gen_nreverse(), NIL, TRANSFORMER, and transformer_arguments.

Referenced by whileloop_to_postcondition().

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

◆ transformer_list_to_argument()

list transformer_list_to_argument ( list  tl)

Returns the list of variables modified by at least one transformer in tl.

Parameters
tll

Definition at line 753 of file transformer_list.c.

754 {
755  list vl = NIL;
756 
757  FOREACH(TRANSFORMER, t, tl) {
759  if(!gen_in_list_p(v, vl))
760  vl = CONS(ENTITY, v, vl);
761  }
762  }
763 
764  vl = gen_nreverse(vl);
765 
766  return vl;
767 }

References CONS, ENTITY, FOREACH, gen_in_list_p(), gen_nreverse(), NIL, TRANSFORMER, and transformer_arguments.

Referenced by transformer_list_multiple_closure_to_precondition().

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

◆ transformer_list_to_transformer()

transformer transformer_list_to_transformer ( list  ltl)

Reduce the transformer list ltl to one transformer using the convex hull operator.

Parameters
ltltl

Definition at line 434 of file transformer_list.c.

435 {
436  return generic_transformer_list_to_transformer(ltl, false);
437 }

References generic_transformer_list_to_transformer().

Referenced by complete_any_loop_transformer(), complete_repeatloop_transformer(), new_complete_whileloop_transformer(), transformer_list_closure_to_precondition_depth_two(), and transformer_list_closure_to_precondition_max_depth().

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

◆ transformer_list_transitive_closure()

transformer transformer_list_transitive_closure ( list  tfl)

Compute (U tfl)*.

Parameters
tflfl

Definition at line 1141 of file transformer_list.c.

1142 {
1144 }
transformer transformer_list_generic_transitive_closure(list tfl, bool star_p)
Computation of an upper approximation of a transitive closure using constraints on the discrete deriv...

References transformer_list_generic_transitive_closure().

Referenced by transformer_list_closure_to_precondition_depth_two(), transformer_list_closure_to_precondition_max_depth(), and unstructured_to_flow_insensitive_transformer().

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

◆ transformer_list_transitive_closure_plus()

transformer transformer_list_transitive_closure_plus ( list  tfl)

Compute (U tfl)+.

Parameters
tflfl

Definition at line 1147 of file transformer_list.c.

1148 {
1150 }

References transformer_list_generic_transitive_closure().

Referenced by dag_or_cycle_to_flow_sensitive_postconditions_or_transformers().

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

◆ transformer_list_with_effect()

list transformer_list_with_effect ( list  tl,
entity  v 
)

build a sublist sl of the transformer list tl with transformers that modify the value of variable v

Parameters
tll

Definition at line 771 of file transformer_list.c.

772 {
773  list sl = NIL;
774 
775  FOREACH(TRANSFORMER, t, tl){
777  sl = CONS(TRANSFORMER, t, sl);
778  }
779  sl = gen_nreverse(sl);
780  return sl;
781 }

References CONS, entity_is_argument_p(), FOREACH, gen_nreverse(), NIL, TRANSFORMER, and transformer_arguments.

Referenced by transformer_list_multiple_closure_to_precondition().

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

◆ transformer_normalize()

transformer transformer_normalize ( transformer  t,
int  level 
)

Eliminate (some) rational or integer redundancy.

Remember that integer redundancy elimination may degrade results because some transformer operator such as convex hull use a rational interpretation of the constraints. Unfortunately, no information is given here about the properties used by the different functions of the C3 linear library which are used.

Does not take into account value types. So s=="hello" and s=="world" do not result into an empty transformer. But floating point values are taken into account.

Start with sc_bounded_normalization and then according to level:

0 -> sc_safe_elim_redund(), sc_elim_redund(), sc_inequations_elim_redund(), sc_rational_feasibility_ofl_ctrl()

1 -> sc_nredund(), build_sc_nredund_2pass(), build_sc_nredund_2pass_ofl_ctrl(), sc_normalize(), build_sc_nredund_1pass_ofl_ctrl(), build_sc_nredund_1pass_ofl_ctrl()

sc_normalize() is well documented (in French)

2 -> sc_strong_normalize(), sc_normalize() sc_strong_normalize_and_check_feasibility(), sc_check_inequality_redundancy(),

3 -> sc_strong_normalize2(): resolve the equations first, then deal with inequalities

4 -> sc_normalize2(): well documented; does not detect redundancy in a<=b, b<=c, a<=c

5 -> sc_strong_normalize3(), sc_strong_normalize_and_check_feasibility (ps, sc_rational_feasibility);

6 -> sc_strong_normalize4() sc_strong_normalize_and_check_feasibility2(ps, sc_normalize, variable_name, 2): well documented, deterministic

7 -> sc_strong_normalize5() sc_strong_normalize_and_check_feasibility2(ps, sc_rational_feasibility, variable_name, 2);

8 -> sc_safe_build_sc_nredund_1pass(): not documented build_sc_nredund_1pass(): do not take equations into consideration

See timing information in the comments below.

Automatic variables read in a CATCH block need to be declared volatile as specified by the documentation

Automatic variables read in a CATCH block need to be declared volatile as specified by the documentation

Select one tradeoff between speed and accuracy: enumerated by increasing speeds according to Beatrice

CA

Let start with an easy O(n) phase, unlikely to generate an overflow. It should be placed in another try-cath in order to return a better r2 in case of a later overflow.

This is not sufficient: it is more efficient to put this call directly in sc_normalize().

Our best choice for accuracy, but damned slow on ocean

Beatrice's best choice: does not deal with minmax2 (only) but still requires 74 minutes of real time (55 minutes of CPU time) for ocean preconditions, when applied to each precondition stored.

Only 64 s for ocean, if preconditions are not normalized. But andne, callabsval, dead2, hind, negand, negand2, or, validation_dead_code are not validated any more. Redundancy could always be detected in a trivial way after propagating values from equations into inequalities.

Francois' own: does most of the easy stuff. Fails on mimax2 and sum_prec, but it is somehow more user-friendly because trivial preconditions are not destroyed as redundant. It makes you feel safer.

Result for full precondition normalization on ocean: 114 s for preconditions, 4 minutes between split ocean.f and OCEAN.prec

Same plus a good feasibility test

Similar, but variable are actually substituted which is sometimes painful when a complex equations is used to replace a simple variable in a simple inequality.

Similar, but variables are substituted if they belong to a more or less simple equation, and simpler equations are processed first and a lexicographically minimal variable is chosen when equivalent variables are available.

Same plus a good feasibility test, plus variable selection for elimination, plus equation selection for elimination

Too expensive according to measurements by Beatrice Creusillet to be used anywhere but before storing transformers or preconditions or before printing them. Lots of calls to string operations when C is the analyzed language because variable names used for sorting are easy to extract due to scope information. It is not clear from the information mailed by Beatrice if sc_normalize2 is also too computational but it should be as only the basis of the constraint system is sorted out to normalize r more effectively.

Very expensive: the system is rebuilt by adding constraints one by one

end of TRY

Parameters
levelevel

Definition at line 932 of file transformer.c.

933 {
934  ifdebug(1) {
935  pips_assert("Transformer t is consistent on entrance",
937  }
938 
939  if(!transformer_is_empty_p(t)) {
940  if(float_analyzed_p()) {
943  ifdebug(1)
944  pips_assert("t is consistent after floating point simplification\n",
946  }
947 
948  /* Automatic variables read in a CATCH block need to be declared volatile as
949  * specified by the documentation*/
951 
952  if (!sc_empty_p(r)) {
953  Pbase b = base_dup(sc_base(r));
954  /* Automatic variables read in a CATCH block need to be declared volatile as
955  * specified by the documentation*/
956  Psysteme r2 = sc_dup(r);
957 
958  /* Select one tradeoff between speed and accuracy:
959  * enumerated by increasing speeds according to Beatrice
960  */
961 
963  {
964  /* CA */
965  pips_user_warning("overflow error in redundancy elimination\n");
966  sc_rm(r);
967  r = r2;
968  }
969  TRY
970  {
971  /* Let start with an easy O(n) phase, unlikely to generate an
972  overflow. It should be placed in another try-cath in order
973  to return a better r2 in case of a later overflow. */
974  /* This is not sufficient: it is more efficient to put this
975  call directly in sc_normalize(). */
977 
978  switch(level) {
979 
980  case 0:
981  /* Our best choice for accuracy, but damned slow on ocean */
982  r = sc_safe_elim_redund(r);
983  break;
984 
985  case 1:
986  /* Beatrice's best choice: does not deal with minmax2 (only)
987  * but still requires 74 minutes of real time
988  * (55 minutes of CPU time) for ocean preconditions,
989  * when applied to each precondition stored.
990  *
991  * Only 64 s for ocean, if preconditions are not normalized.
992  * But andne, callabsval, dead2, hind, negand, negand2, or,
993  * validation_dead_code are not validated any more. Redundancy
994  * could always be detected in a trivial way after propagating
995  * values from equations into inequalities.
996  */
997  sc_nredund(&r);
998  //predicate_system(transformer_relation(t)) = r;
999  break;
1000 
1001  case 2:
1002  /* Francois' own: does most of the easy stuff.
1003  * Fails on mimax2 and sum_prec, but it is somehow
1004  * more user-friendly because trivial preconditions are
1005  * not destroyed as redundant. It makes you feel safer.
1006  *
1007  * Result for full precondition normalization on ocean: 114 s
1008  * for preconditions, 4 minutes between split ocean.f and
1009  * OCEAN.prec
1010  */
1011  r = sc_strong_normalize(r);
1012  // predicate_system(transformer_relation(t)) = r;
1013  break;
1014 
1015  case 5:
1016  /* Same plus a good feasibility test
1017  */
1018  r = sc_strong_normalize3(r);
1019  break;
1020 
1021  case 3:
1022  /* Similar, but variable are actually substituted
1023  * which is sometimes painful when a complex equations
1024  * is used to replace a simple variable in a simple
1025  * inequality.
1026  */
1027  r = sc_strong_normalize2(r);
1028  break;
1029  case 6:
1030  /* Similar, but variables are substituted if they belong to
1031  * a more or less simple equation, and simpler equations
1032  * are processed first and a lexicographically minimal
1033  * variable is chosen when equivalent variables are
1034  * available.
1035  */
1036  r = sc_strong_normalize4(r,
1037  (char * (*)(Variable)) external_value_name);
1038  break;
1039 
1040  case 7:
1041  /* Same plus a good feasibility test, plus variable selection
1042  * for elimination, plus equation selection for elimination
1043  */
1044  r = sc_strong_normalize5(r,
1045  (char * (*)(Variable)) external_value_name);
1046  break;
1047 
1048  case 4:
1049  /* Too expensive according to measurements by Beatrice
1050  * Creusillet to be used anywhere but before storing
1051  * transformers or preconditions or before printing
1052  * them. Lots of calls to string operations when C is the
1053  * analyzed language because variable names used for sorting
1054  * are easy to extract due to scope information. It is not
1055  * clear from the information mailed by Beatrice if
1056  * sc_normalize2 is also too computational but it should be
1057  * as only the basis of the constraint system is sorted out
1058  * to normalize r more effectively.
1059  */
1061  r = sc_normalize2(r);
1062  break;
1063 
1064  case 8:
1065  /* Very expensive: the system is rebuilt by adding constraints
1066  * one by one
1067  */
1069  break;
1070 
1071  default:
1072  pips_internal_error("unknown level %d", level);
1073  }
1074 
1075  sc_rm(r2), r2 = NULL;
1077  } /* end of TRY */
1078 
1079  if (SC_EMPTY_P(r)) {
1080  r = sc_empty(BASE_NULLE);
1081  }
1082  else
1083  base_rm(b), b=BASE_NULLE;
1084 
1085  r->dimension = vect_size(r->base);
1086 
1087  if(sc_empty_p(r)) {
1088  //empty_transformer(t);
1092  }
1093  else
1095  }
1096  }
1097  ifdebug(8) {
1098  fprintf(stderr, "After normalization of transformer t=%p at level %d:\n",
1099  t, level);
1101  }
1102 
1103  ifdebug(1) {
1104  pips_assert("Transformer t is consistent on exit",
1106  }
1107 
1108  return t;
1109 }
void sc_safe_build_sc_nredund_1pass(Psysteme volatile *ps)
Psysteme sc_safe_elim_redund(Psysteme ps)
Same as above, but the basis is preserved and sc_empty is returned is the system is not feasible.
#define level
Psysteme sc_strong_normalize3(Psysteme ps)
Psysteme sc_strong_normalize5(Psysteme ps, char *(*variable_name)(Variable))
Psysteme sc_strong_normalize2(volatile Psysteme ps)
Psysteme sc_strong_normalize2(Psysteme ps)
Psysteme sc_bounded_normalization(Psysteme ps)
Eliminate trivially redundant integer constraint using a O(n x d^2) algorithm, where n is the number ...
Psysteme sc_strong_normalize(Psysteme ps)
Psysteme sc_strong_normalize(Psysteme ps)
static int varval_value_name_is_inferior_p(Pvecteur *pvarval1, Pvecteur *pvarval2)
Definition: transformer.c:870
Psysteme simplify_float_constraint_system(Psysteme ps)
Simplify float constraints and possibly detect.
Definition: transformer.c:2146
bool float_analyzed_p(void)
Definition: value.c:315
void vect_sort_in_place(Pvecteur *pv, int *compare)
void vect_sort_in_place(pv, compare) Pvecteur *pv; int (*compare)(Pvecteur *, Pvecteur *);
Definition: unaires.c:290

References Ssysteme::base, base_dup(), BASE_NULLE, base_rm, CATCH, Ssysteme::dimension, entity_local_name(), external_value_name(), float_analyzed_p(), fprint_transformer(), fprintf(), free_arguments(), ifdebug, level, NIL, overflow_error, pips_assert, pips_internal_error, pips_user_warning, predicate_system, sc_bounded_normalization(), sc_dup(), sc_empty(), sc_empty_p(), sc_normalize2(), sc_rm(), sc_safe_build_sc_nredund_1pass(), sc_safe_elim_redund(), sc_strong_normalize(), sc_strong_normalize2(), sc_strong_normalize3(), sc_strong_normalize4(), sc_strong_normalize5(), simplify_float_constraint_system(), transformer_arguments, transformer_consistency_p(), transformer_consistent_p(), transformer_is_empty_p(), transformer_relation, TRY, UNCATCH, varval_value_name_is_inferior_p(), vect_size(), and vect_sort_in_place().

Referenced by any_expressions_to_transformer(), any_user_call_site_to_transformer(), block_to_postcondition(), block_to_transformer(), block_to_transformer_list(), call_site_to_module_precondition_text(), call_to_transformer(), combine_transformer_lists(), complete_any_loop_transformer_list(), complete_loop_transformer(), complete_loop_transformer_list(), condition_to_transformer(), declarations_to_transformer(), declarations_to_transformer_list(), expression_multiply_sizeof_to_transformer(), expressions_to_transformer(), generic_module_name_to_transformers(), integer_multiply_to_transformer(), logical_binary_function_to_transformer(), loop_to_enter_transformer(), module_name_to_total_preconditions(), ordinary_summary_precondition(), propagate_preconditions_in_declarations(), statement_to_postcondition(), statement_to_total_precondition(), statement_to_transformer(), statement_to_transformer_list(), summary_precondition(), summary_total_postcondition(), test_to_postcondition(), test_to_total_precondition(), transformer_add_any_relation_information(), transformer_convex_hull(), transformer_list_add_combination(), transformer_safe_normalize(), and update_precondition_with_call_site_preconditions().

+ 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

Parameters
tff

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 }
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
Psysteme sc_elim_redund(Psysteme ps)
Psysteme sc_elim_redund(Psysteme ps): elimination des contraintes lineaires redondantes dans le syste...

◆ transformer_projectable_values()

list transformer_projectable_values ( transformer  tf)
Parameters
tff

Definition at line 827 of file basic.c.

828 {
829  list proj = NIL;
831  Pbase b = BASE_UNDEFINED;
832 
833  for(b=sc_base(sc); !BASE_NULLE_P(b); b = vecteur_succ(b)) {
834  entity v = (entity) vecteur_var(b);
835 
836  proj = CONS(ENTITY, v, proj);
837  }
838 
839  return proj;
840 }

References BASE_NULLE_P, BASE_UNDEFINED, CONS, ENTITY, NIL, predicate_system, transformer_relation, vecteur_succ, and vecteur_var.

Referenced by recompute_loop_transformer().

+ Here is the caller graph for this function:

◆ transformer_projection()

transformer transformer_projection ( transformer  t,
list  args 
)

values in args must be in t's base

transformer transformer_projection(transformer t, cons * args): projection of t along the hyperplane defined by values in args; this generate a projection and not a cylinder based on the projection

use the most complex/complete redundancy elimination in Linear

args is not modified. t is modified by side effects.

sc_safe_elim_redund() may increase the rational generating system

t = transformer_projection_with_redundancy_elimination(t, args, sc_safe_elim_redund);

Parameters
argsrgs

Definition at line 1267 of file transformer.c.

1268 {
1269  /* sc_safe_elim_redund() may increase the rational generating system */
1270  /* t = transformer_projection_with_redundancy_elimination(t, args,
1271  sc_safe_elim_redund); */
1274  return t;
1275 }
Psysteme sc_safe_normalize(Psysteme ps)
Psysteme sc_safe_normalize(Psysteme ps) output : ps, normalized.
transformer transformer_projection_with_redundancy_elimination(transformer t, list args, Psysteme(*elim)(Psysteme))
It is not clear if this function projects values or variables.
Definition: transformer.c:1322

References sc_safe_normalize(), and transformer_projection_with_redundancy_elimination().

Referenced by generic_transformer_intra_to_inter(), new_array_element_backward_substitution_in_transformer(), precondition_to_abstract_store(), recompute_loop_transformer(), safe_transformer_projection(), transformer_add_loop_index_initialization(), transformer_arguments_projection(), transformer_filter_subsumed_variables(), transformer_formal_parameter_projection(), transformer_return_value_projection(), translate_global_value(), and value_passing_summary_transformer().

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

◆ transformer_projection_with_redundancy_elimination()

transformer transformer_projection_with_redundancy_elimination ( transformer  t,
list  args,
Psysteme(*)(Psysteme elim 
)

It is not clear if this function projects values or variables.

If variables were projected, all values associated to a variable should also be projected. If values are projected and the transformer argument updated using args, old values should not be left in the basis when a new value is projected and its associated variable removed from tthe argument.

New values are identical to variables which makes it confusing.

The implementation, and the signature, are aware of the nature of the underlying predicate.

Parameters
argsrgs

Definition at line 1322 of file transformer.c.

1326 {
1328  (t, args, elim, true);
1329 }
transformer transformer_projection_with_redundancy_elimination_and_check(volatile transformer t, list args, Psysteme(*elim)(Psysteme), bool check_consistency_p)
Definition: transformer.c:1343

References transformer_projection_with_redundancy_elimination_and_check().

Referenced by precondition_intra_to_inter(), transformer_projection(), transformer_range(), and transformer_temporary_value_projection().

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

◆ transformer_projection_with_redundancy_elimination_and_check()

transformer transformer_projection_with_redundancy_elimination_and_check ( volatile  transformer,
list  args,
Psysteme(*)(Psysteme elim,
bool  check_consistency_p 
)

Library Linear/sc contains several reundancy elimination functions: sc_elim_redund() build_sc_nredund_2pass_ofl_ctrl() — if it had the same profile... ... no_elim() is provided here to obtain the fastest possible projection

Automatic variables read in a CATCH block need to be declared volatile as specified by the documentation

sc_fprint(stderr, r, exernal_value_name);

sc_fprint(stderr, r, (char * (*)(Variable)) entity_local_name);

A side effect of transformer_empty_p() is to normalize the transformer.

This is very expensive before a projection. empty_transformer_p()

Step 1: get rid of unwanted values in the relation r and in the basis

Automatic variables read in a CATCH block need to be declared volatile as specified by the documentation

FC

sc_projection_along_variable_ofl_ctrl_timeout_ctrl

could eliminate redundancy at each projection stage to avoid explosion of the constraint number... however it is pretty expensive to do so. But we explode with NPRIO in FPPP (Spec CFP'95 benchmark). A heuristic could apply redundacy elimination from time to time?

Eliminate trivial redundant constraints generated by the projection

Probably redundant with what happens in elim()

if (SC_EMPTY_P(r)) { r = sc_empty(BASE_NULLE); sc_base_remove_variable(r,(Variable) e); } else base_rm(b); }

sc_fprint(stderr, r, exernal_value_name);

Step 2: eliminate redundancy only/again once projections have all been performed because redundancy elimination is expensive and because most variables are exactly projected because they appear in at least one equation

Should we use b or not? It does make some mathematical sense but it is not compatible with the argument list which should not be empty if old values appear in the basis. And the basis should not be used, even in convex hulls if the emptiness is detected first.

get rid of a useless basis

sc_fprint(stderr, r, exernal_value_name);

Step 3: compute new_args, but beware of left over old values!

e must be kept if it is not in args

The variable is going to be dropped from the argument list

Must be a variable from a module which is not the current module

Step 4: update the relation and the arguments field for t

the relation is updated by side effect FI ? Maybe not if SC_EMPTY(r) 1 Feb. 94

replace the old arguments by the new one, except if the constraint system is not feasible

sc_fprint(stderr, r, exernal_value_name);

Weak, because return value may still be present for functions.

Parameters
argsrgs
check_consistency_pheck_consistency_p

Definition at line 1343 of file transformer.c.

1348 {
1349  /* Library Linear/sc contains several reundancy elimination functions:
1350  * sc_elim_redund()
1351  * build_sc_nredund_2pass_ofl_ctrl() --- if it had the same profile...
1352  * ...
1353  * no_elim() is provided here to obtain the fastest possible projection
1354  */
1355  volatile list new_args = NIL;
1356  /* Automatic variables read in a CATCH block need to be declared volatile as
1357  * specified by the documentation*/
1359 
1360  ifdebug(9) {
1361  pips_debug(9, "Begin for transformer %p\n", t);
1362  /* sc_fprint(stderr, r, exernal_value_name); */
1363  /* sc_fprint(stderr, r, (char * (*)(Variable)) entity_local_name); */
1365  pips_debug(9, "and entities to be projected: ");
1366  print_entities(args);
1367  }
1368 
1369  pips_assert("t is weakly consistent", transformer_weak_consistency_p(t));
1370 
1371  /* A side effect of transformer_empty_p() is to normalize the transformer.
1372  *
1373  * This is very expensive before a projection. empty_transformer_p()
1374  */
1375  if(transformer_empty_p(t)) {
1376  t = empty_transformer(t);
1377  }
1378  else if(!ENDP(args)) {
1379  volatile list cea;
1380  Pbase mb = sc_to_minimal_basis(r); // Get the variables with non-zero coefficients
1381 
1382  /* Step 1: get rid of unwanted values in the relation r and in the basis */
1383  for (cea = args ; !ENDP(cea); POP(cea)) {
1384  /* Automatic variables read in a CATCH block need to be declared
1385  * volatile as specified by the documentation*/
1386  entity volatile e = ENTITY(CAR(cea));
1387  pips_assert("base contains variable to project...",
1388  base_contains_variable_p(sc_base(r), (Variable) e));
1389 
1390  pips_debug(9, "Projection of %s\n", entity_name(e));
1391 
1392  if(base_contains_variable_p(mb, (Variable) e)) {
1393  // The variable appears with a non-zero coefficient in at least one constraint
1395  {
1396  /* FC */
1397  pips_user_warning("overflow error in projection of %s, "
1398  "variable eliminated\n",
1399  entity_name(e));
1400  r = sc_elim_var(r, (Variable) e);
1401  }
1402  TRY
1403  {
1404  /* sc_projection_along_variable_ofl_ctrl_timeout_ctrl */
1405  sc_projection_along_variable_ofl_ctrl
1406  (&r,(Variable) e, NO_OFL_CTRL);
1408  }
1409 
1410  /* could eliminate redundancy at each projection stage to avoid
1411  * explosion of the constraint number... however it is pretty
1412  * expensive to do so. But we explode with NPRIO in FPPP (Spec
1413  * CFP'95 benchmark). A heuristic could apply redundacy elimination
1414  * from time to time?
1415  *
1416  */
1417 
1418  if(true) {
1419  // if (!sc_empty_p(r)) {
1420  // Pbase b = base_dup(sc_base(r));
1421 
1422  /* Eliminate trivial redundant constraints generated by the
1423  projection */
1424  /* Probably redundant with what happens in elim() */
1425  r = sc_bounded_normalization(r);
1426 
1427  r = elim(r);
1428  /* if (SC_EMPTY_P(r)) {
1429  r = sc_empty(BASE_NULLE);
1430  sc_base_remove_variable(r,(Variable) e);
1431  }
1432  else base_rm(b);
1433  }*/
1434 
1435  }
1436  }
1437 
1439 
1440  ifdebug(9) {
1441  pips_debug(9, "System after projection of %s\n", entity_name(e));
1442  /* sc_fprint(stderr, r, exernal_value_name); */
1443  sc_fprint(stderr, r, (char * (*)(Variable)) entity_global_name);
1444  }
1445  }
1446  vect_rm(mb);
1447 
1448  /* Step 2: eliminate redundancy only/again once projections have all
1449  * been performed because redundancy elimination is
1450  * expensive and because most variables are exactly
1451  * projected because they appear in at least one equation
1452  */
1453  if (!sc_empty_p(r)) {
1454  Pbase b = base_dup(sc_base(r));
1455  r = elim(r);
1456  if (SC_EMPTY_P(r)) {
1457  /* Should we use b or not? It does make some mathematical sense
1458  but it is not compatible with the argument list which should
1459  not be empty if old values appear in the basis. And the basis
1460  should not be used, even in convex hulls if the emptiness is
1461  detected first. */
1462  r = sc_empty(BASE_NULLE);
1463  base_rm(b);
1464  }
1465  else {
1466  base_rm(b);
1467  }
1468  }
1469  else {
1470  /* get rid of a useless basis */
1471  base_rm(sc_base(r));
1472  sc_base(r) = BASE_NULLE;
1473  }
1474 
1475  r->dimension = vect_size(r->base);
1476 
1477  ifdebug(9) {
1478  pips_debug(9, "System after redundancy elimination\n");
1479  /* sc_fprint(stderr, r, exernal_value_name); */
1480  sc_fprint(stderr, r, (char * (*)(Variable)) entity_global_name);
1481  }
1482 
1483  /* Step 3: compute new_args, but beware of left over old values! */
1486  entity v = value_to_variable(e);
1487 
1488  if((entity) gen_find_eq(e, args) == (entity) chunk_undefined)
1489  {
1490  /* e must be kept if it is not in args */
1491  new_args = arguments_add_entity(new_args, e);
1492  }
1493  else {
1494  /* The variable is going to be dropped from the argument list */
1495  entity old_e = entity_undefined;
1496 
1497  if(entity_has_values_p(v)) {
1498  old_e = entity_to_old_value(v);
1499  }
1500  else {
1501  /* Must be a variable from a module which is not the current module */
1503  }
1504 
1505  if(check_consistency_p
1506  && base_contains_variable_p(sc_base(r), (Variable) old_e)) {
1507  fprintf(stderr, "Value %s should have been eliminated earlier\n",
1508  entity_name(old_e));
1510  pips_internal_error("Wrong set of projected variables");
1511  }
1512  }
1513  }
1514  }
1515 
1516  /* Step 4: update the relation and the arguments field for t */
1517 
1518  /* the relation is updated by side effect FI ?
1519  * Maybe not if SC_EMPTY(r) 1 Feb. 94 */
1521 
1522  /* replace the old arguments by the new one, except if the
1523  constraint system is not feasible */
1525  if(sc_empty_p(r)) {
1526  transformer_arguments(t) = NULL;
1527  gen_free_list(new_args);
1528  }
1529  else
1530  transformer_arguments(t) = new_args;
1531  }
1532 
1533  ifdebug(9) {
1534  pips_debug(9, "Transformer after argument list update\n");
1535  /* sc_fprint(stderr, r, exernal_value_name); */
1537  }
1538 
1539  ifdebug(1) {
1540  /* Weak, because return value may still be present for functions. */
1541  if(check_consistency_p)
1542  pips_assert("After projection and redundancy elimination,"
1543  " transformer t is consistent",
1545  }
1546  pips_debug(9, "End for t=%p\n", t);
1547 
1548  return t;
1549 }
#define chunk_undefined
obsolete
Definition: genC.h:79
void * gen_find_eq(const void *item, const list seq)
Definition: list.c:422
void print_entities(list l)
Definition: entity.c:167
entity global_new_value_to_global_old_value(entity)
Definition: value.c:716

References arguments_add_entity(), Ssysteme::base, base_contains_variable_p(), base_dup(), BASE_NULLE, base_rm, CAR, CATCH, chunk_undefined, Ssysteme::dimension, empty_transformer(), ENDP, ENTITY, entity_global_name(), entity_has_values_p(), entity_name, entity_to_old_value(), entity_undefined, FOREACH, fprint_transformer(), fprintf(), gen_find_eq(), gen_free_list(), global_new_value_to_global_old_value(), ifdebug, local_temporary_value_entity_p(), newgen_Psysteme, NIL, NO_OFL_CTRL, overflow_error, pips_assert, pips_debug, pips_internal_error, pips_user_warning, POP, predicate_system, predicate_system_, print_entities(), sc_base_remove_variable(), sc_bounded_normalization(), sc_elim_var(), sc_empty(), sc_empty_p(), sc_fprint(), sc_to_minimal_basis(), transformer_arguments, transformer_empty_p(), transformer_relation, transformer_weak_consistency_p(), TRY, UNCATCH, value_to_variable(), vect_rm(), and vect_size().

Referenced by transformer_projection_with_redundancy_elimination(), and transformer_projection_without_check().

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

◆ transformer_projection_without_check()

transformer transformer_projection_without_check ( transformer  t,
list  args,
Psysteme(*)(Psysteme elim 
)

In some cases, you know the projection will result in a non-consistent transformer that will be fixed later.

The input transformer is nevertheless expected weakly consistent.

Parameters
argsrgs

Definition at line 1334 of file transformer.c.

1338 {
1340  (t, args, elim, false);
1341 }

References transformer_projection_with_redundancy_elimination_and_check().

Referenced by transformer_to_domain().

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

◆ transformer_range()

transformer transformer_range ( transformer  tf)

Return the range of relation tf in a newly allocated transformer.

Projection of all old values.

A variable may be modified but its old value does not have to appear in the basis. Although the opposite is wrong.

rtf = transformer_projection(rtf, args);

Parameters
tff

Definition at line 714 of file transformer.c.

715 {
716  transformer rtf = transformer_dup(tf);
717  list args = NIL;
719  Pbase b = sc_base(sc);
720 
722  entity ov = entity_to_old_value(a);
723 
724  /* A variable may be modified but its old value does not have to
725  appear in the basis. Although the opposite is wrong. */
726  if(base_contains_variable_p(b, (Variable) ov)) {
727  args = CONS(ENTITY, ov, args);
728  }
729  }
730 
731  /* rtf = transformer_projection(rtf, args); */
733  sc_identity);
734 
735  gen_free_list(args);
736 
738  transformer_arguments(rtf) = NIL;
739 
740  return rtf;
741 }
static Psysteme sc_identity(Psysteme sc)
Predicate transformer package: sc complexity level.
Definition: transformer.c:52

References base_contains_variable_p(), CONS, ENTITY, entity_to_old_value(), FOREACH, gen_free_list(), NIL, predicate_system, sc_identity(), transformer_arguments, transformer_dup(), transformer_projection_with_redundancy_elimination(), and transformer_relation.

Referenced by add_index_bound_conditions(), add_loop_index_initialization(), addition_operation_to_transformer(), any_conditional_to_transformer(), any_expressions_to_transformer(), any_loop_to_k_transformer(), any_transformer_to_k_closure(), assign_rhs_to_reflhs_to_transformer(), bitwise_xor_to_transformer(), block_to_transformer_list(), c_data_to_prec_for_variables(), call_to_postcondition(), complete_loop_transformer(), condition_to_transformer(), conditional_to_transformer(), declaration_to_transformer(), declaration_to_transformer_list(), declarations_to_transformer(), declarations_to_transformer_list(), dimensions_to_transformer(), do_array_expansion(), do_solve_hardware_constraints_on_nb_proc(), do_solve_hardware_constraints_on_volume(), effects_to_dma(), eval_linear_expression(), expression_multiply_sizeof_to_transformer(), expressions_to_transformer(), fortran_data_to_prec_for_variables(), generic_unary_operation_to_transformer(), integer_binary_operation_to_transformer(), integer_left_shift_to_transformer(), integer_multiply_to_transformer(), integer_power_to_transformer(), logical_not_to_transformer(), loop_body_transformer_add_entry_and_iteration_information(), loop_to_postcondition(), loop_to_transformer(), memorize_precondition_for_summary_precondition(), modulo_to_transformer(), new_loop_to_transformer(), partial_eval_min_or_max_operator(), pointer_unary_operation_to_transformer(), precondition_add_condition_information(), process_ready_node(), safe_assigned_expression_to_transformer(), safe_assigned_expression_to_transformer_list(), statement_to_total_precondition(), statement_to_transformer(), statement_to_transformer_list(), transformer_add_any_relation_information(), transformer_combine(), transformer_intersect_range_with_domain(), transformer_list_multiple_closure_to_precondition(), transformer_safe_range(), transformers_range(), unstructured_to_flow_sensitive_postconditions_or_transformers(), unstructured_to_postconditions(), and whileloop_to_postcondition().

+ Here is the call graph for this function:

◆ transformer_range_intersection()

transformer transformer_range_intersection ( transformer  tf,
transformer  r 
)

Allocate a new transformer rtf that is tf with its range restricted by the range r.

As a range, r is assumed to have no arguments.

Parameters
tff

Definition at line 830 of file transformer.c.

831 {
832  pips_assert("r does not involve old values and has no arguments",
835 
836  return rtf;
837 }

References ENDP, pips_assert, transformer_arguments, and transformer_image_intersection().

Referenced by add_index_bound_conditions(), integer_expression_and_precondition_to_integer_interval(), process_ready_node(), and transformer_combine().

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

◆ transformer_return_value_projection()

transformer transformer_return_value_projection ( entity  f,
transformer  t 
)

Project return values that are not linked to function f.

Almost identical to transformer_formal_parameter_projection(). A lambda expression should be passed for the filtering.

Dealing with an interprocedural transformer, weak consistency is not true

pips_assert("t is weakly consistent", transformer_weak_consistency_p(t));

Definition at line 1220 of file transformer.c.

1221 {
1223  Pbase b = sc_base(sc);
1224  Pbase cd = BASE_UNDEFINED;
1225  list fpl = NIL;
1226 
1227  /* Dealing with an interprocedural transformer, weak consistency is
1228  not true */
1229  /* pips_assert("t is weakly consistent",
1230  transformer_weak_consistency_p(t));*/
1231  pips_assert("sc is consistent", sc_weak_consistent_p(sc));
1232  pips_assert("t is weakly consistent", transformer_weak_consistency_p(t));
1233 
1234  for(cd = b; !BASE_NULLE_P(cd); cd = vecteur_succ(cd)) {
1235  entity val = (entity) vecteur_var(cd);
1236  entity var = value_to_variable(val);
1237  storage s = entity_storage(var);
1238 
1239  if(storage_return_p(s) && storage_return(s)!=f)
1240  fpl = CONS(ENTITY, var, fpl);
1241  }
1242 
1243  ifdebug(1) {
1244  pips_debug(1, "Transformer before projection:\n");
1245  dump_transformer(t);
1246  pips_debug(1, "Projected variables:\n");
1247  print_entities(fpl);
1248  fprintf(stderr, "\n");
1249  }
1250 
1251  t = transformer_projection(t, fpl);
1252 
1253  gen_free_list(fpl);
1254 
1255  return t;
1256 }
#define storage_return(x)
Definition: ri.h:2518

References BASE_NULLE_P, BASE_UNDEFINED, CONS, dump_transformer, ENTITY, entity_storage, f(), fprintf(), gen_free_list(), ifdebug, NIL, pips_assert, pips_debug, predicate_system, print_entities(), sc_weak_consistent_p(), storage_return, storage_return_p, transformer_projection(), transformer_relation, transformer_weak_consistency_p(), value_to_variable(), vecteur_succ, and vecteur_var.

Referenced by struct_reference_assignment_or_equality_to_transformer().

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

◆ transformer_safe_affect_transformer_p()

bool transformer_safe_affect_transformer_p ( transformer  tf1,
transformer  tf2 
)
Parameters
tf1f1
tf2f2

Definition at line 1894 of file transformer.c.

1895 {
1896  bool affect_p = false;
1897 
1899  affect_p = transformer_affect_transformer_p(tf1, tf2);
1900 
1901  return affect_p;
1902 }
bool transformer_affect_transformer_p(transformer tf1, transformer tf2)
Transformer tf1 affects transformer tf2 if values modified by tf1 appear in any constraint of tf2.
Definition: transformer.c:1870

References transformer_affect_transformer_p(), and transformer_undefined_p.

Referenced by transformer_safe_combine_with_warnings().

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

◆ transformer_safe_apply()

◆ transformer_safe_combine_with_warnings()

transformer transformer_safe_combine_with_warnings ( transformer  tf1,
transformer  tf2 
)

Transformer tf1 and tf2 are supposed to be independent but they may interfere, for instance because subexpressions have non-standard conformant side effects.

tf12 is a newly allocated transformer with no sharing with tf1 or tf2 (theoretically).

Intersection is not powerful enough to cope with side effects. But side effects can be dealt with only if the operation order is known when the standard is violated. We assume here a right to left evaluation.

No side effects at all

Parameters
tf1f1
tf2f2

Definition at line 493 of file transformer.c.

494 {
496 
497  /* Intersection is not powerful enough to cope with side effects. But
498  side effects can be dealt with only if the operation order is known
499  when the standard is violated. We assume here a right to left evaluation. */
501  pips_debug(9, "Side effects of tf2 on tf1\n");
502  pips_user_warning("Non standard compliant code: side effect in part\n"
503  "of an expression affects variable(s) used in a later part\n");
504  tf12 = transformer_combine(tf1, tf2);
505  }
506  else if (transformer_safe_affect_transformer_p(tf2, tf1)){
507  pips_debug(9, "Side effects of tf2 on tf1\n");
508  pips_user_warning("Non standard compliant code: side effect in part\n"
509  "of an expression affect variables used in an earlier part\n");
510  tf12 = transformer_combine(tf1, tf2);
511  }
512  else {
513  pips_debug(9, "No adversary side effects\n");
517  /* No side effects at all */
518  pips_debug(9, "No side effects at all\n");
519  tf12 = transformer_safe_intersection(tf1, tf2);
520  free_transformer(tf1);
521  }
522  else {
523  pips_debug(9, "Side effects on other variables\n");
524  tf12 = transformer_combine(tf1, tf2);
525  }
526  }
527  return tf12;
528 }
transformer transformer_safe_intersection(transformer t1, transformer t2)
Allocate a new transformer.
Definition: transformer.c:639
bool transformer_safe_affect_transformer_p(transformer tf1, transformer tf2)
Definition: transformer.c:1894

References ENDP, free_transformer(), pips_debug, pips_user_warning, transformer_arguments, transformer_combine(), transformer_safe_affect_transformer_p(), transformer_safe_intersection(), transformer_undefined, and transformer_undefined_p.

Referenced by addition_operation_to_transformer(), and transformer_add_any_relation_information().

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

◆ transformer_safe_domain()

transformer transformer_safe_domain ( transformer  tf)
Parameters
tff

Definition at line 815 of file transformer.c.

816 {
818 
819  if(!transformer_undefined_p(tf)) {
820  dtf = transformer_to_domain(tf);
821  }
822  return dtf;
823 }

References transformer_to_domain(), transformer_undefined, and transformer_undefined_p.

+ Here is the call graph for this function:

◆ transformer_safe_domain_intersection()

transformer transformer_safe_domain_intersection ( transformer  tf,
transformer  pre 
)

If tf and pre are defined, update tf.

If tf is defined and pre is undefined, return tf unchanged. If tf and pre are undefined, return tf unchanged. If tf is undefined and pre is defined, we could exploit pre or return undefined.

Parameters
tff
prere

Definition at line 696 of file transformer.c.

698 {
699  if(!transformer_undefined_p(pre)) {
700  if(transformer_undefined_p(tf)) {
702  }
703  else {
704  tf = transformer_domain_intersection(tf, pre);
705  }
706  }
707 
708  return tf;
709 }

References transformer_domain_intersection(), transformer_identity(), and transformer_undefined_p.

Referenced by call_to_transformer().

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

◆ transformer_safe_image_intersection()

transformer transformer_safe_image_intersection ( transformer  t1,
transformer  t2 
)

Allocate a new transformer.

Parameters
t11
t22

Definition at line 647 of file transformer.c.

648 {
650 
651  return tf;
652 }
static transformer transformer_safe_general_intersection(transformer t1, transformer t2, bool image_only)
Allocate a new transformer.
Definition: transformer.c:622

References transformer_safe_general_intersection().

Referenced by add_formal_to_actual_bindings(), addition_operation_to_transformer(), fortran_user_call_to_transformer(), generic_abs_to_transformer(), generic_minmax_to_transformer(), iabs_to_transformer(), integer_minmax_to_transformer(), loop_bound_evaluation_to_transformer(), and transformer_add_any_relation_information().

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

◆ transformer_safe_intersection()

transformer transformer_safe_intersection ( transformer  t1,
transformer  t2 
)

Allocate a new transformer.

Parameters
t11
t22

Definition at line 639 of file transformer.c.

640 {
642 
643  return tf;
644 }

References transformer_safe_general_intersection().

Referenced by logical_binary_operation_to_transformer(), loop_bound_evaluation_to_transformer(), transformer_safe_combine_with_warnings(), and unary_minus_operation_to_transformer().

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

◆ transformer_safe_inverse_apply()

transformer transformer_safe_inverse_apply ( transformer  tf,
transformer  post 
)
Parameters
tff
postost

Definition at line 1686 of file transformer.c.

1687 {
1689 
1691  pre = transformer_inverse_apply(tf, post);
1692 
1693  return pre;
1694 }
transformer transformer_inverse_apply(transformer tf, transformer post)
transformer transformer_inverse_apply(transformer tf, transformer post): apply transformer tf on prec...
Definition: transformer.c:1657

References transformer_inverse_apply(), transformer_undefined, and transformer_undefined_p.

+ Here is the call graph for this function:

◆ transformer_safe_normalize()

transformer transformer_safe_normalize ( transformer  t,
int  level 
)
Parameters
levelevel

Definition at line 1111 of file transformer.c.

1112 {
1113  if(!transformer_undefined_p(t)) {
1114  t = transformer_normalize(t, level);
1115  }
1116  return t;
1117 }

References level, transformer_normalize(), and transformer_undefined_p.

Referenced by block_to_transformer(), block_to_transformer_list(), c_data_to_prec_for_variables(), declarations_to_transformer(), declarations_to_transformer_list(), fortran_data_to_prec_for_variables(), propagate_preconditions_in_declarations(), and transformers_safe_normalize().

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

◆ transformer_safe_range()

transformer transformer_safe_range ( transformer  tf)
Parameters
tff

Definition at line 743 of file transformer.c.

744 {
746 
747  if(!transformer_undefined_p(tf)) {
748  rtf = transformer_range(tf);
749  }
750  return rtf;
751 }

References transformer_range(), transformer_undefined, and transformer_undefined_p.

Referenced by loop_initialization_to_transformer().

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

◆ transformer_safe_value_substitute()

transformer transformer_safe_value_substitute ( transformer  t,
entity  e1,
entity  e2 
)
Parameters
e11
e22

Definition at line 2048 of file transformer.c.

2051 {
2052  if(!transformer_undefined_p(t))
2053  t = transformer_value_substitute(t, e1, e2);
2054 
2055  return t;
2056 }

References transformer_undefined_p, and transformer_value_substitute().

Referenced by add_formal_to_actual_bindings().

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

◆ transformer_strongly_empty_p()

bool transformer_strongly_empty_p ( transformer  t)

If true is returned, the transformer certainly is empty.

If false is returned, the transformer still might be empty, but it's not likely at all...

Definition at line 2465 of file transformer.c.

2466 {
2468  return empty_p;
2469 }

References parametric_transformer_empty_p(), and sc_strong_normalize5().

Referenced by statement_strongly_feasible_p().

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

◆ transformer_temporary_value_projection()

transformer transformer_temporary_value_projection ( transformer  tf)

tf = transformer_projection(tf, tv);

tf = transformer_projection_with_redundancy_elimination(tf, tv, sc_identity);

Parameters
tff

Definition at line 1149 of file transformer.c.

1150 {
1151  list tv = NIL;
1152 
1153  if(number_of_temporary_values()>0) {
1155  Pbase b = BASE_NULLE;
1156 
1157  for(b = sc_base(r); !BASE_NULLE_P(b); b = vecteur_succ(b)) {
1158  entity e = (entity) vecteur_var(b);
1160  tv = CONS(ENTITY, e, tv);
1161  }
1162  }
1163  /* tf = transformer_projection(tf, tv); */
1164  /* tf = transformer_projection_with_redundancy_elimination(tf, tv, sc_identity); */
1166  }
1167  else ifdebug(1) {
1169  Pbase b = BASE_NULLE;
1170 
1171  for(b = sc_base(r); !BASE_NULLE_P(b); b = vecteur_succ(b)) {
1172  entity e = (entity) vecteur_var(b);
1174  tv = CONS(ENTITY, e, tv);
1175  }
1176  }
1177  pips_assert("No temporary values exist in the system since a reset "
1178  "counter for them has been performed\n", ENDP(tv));
1179  }
1180 
1181  gen_free_list(tv);
1182 
1183  return tf;
1184 }
int number_of_temporary_values(void)
Definition: value.c:255

References BASE_NULLE, BASE_NULLE_P, CONS, ENDP, ENTITY, gen_free_list(), ifdebug, local_temporary_value_entity_p(), NIL, number_of_temporary_values(), pips_assert, predicate_system, sc_safe_normalize(), transformer_projection_with_redundancy_elimination(), transformer_relation, vecteur_succ, and vecteur_var.

Referenced by add_index_bound_conditions(), any_scalar_assign_to_transformer_list(), any_scalar_assign_to_transformer_without_effect(), assigned_expression_to_transformer(), assigned_expression_to_transformer_list(), c_data_to_prec_for_variables(), c_return_to_transformer(), c_user_call_to_transformer(), call_to_transformer(), condition_to_transformer(), expression_to_transformer(), fortran_data_to_prec_for_variables(), fortran_user_call_to_transformer(), loop_bound_evaluation_to_transformer(), loop_to_enter_transformer(), precondition_add_condition_information(), test_to_postcondition(), test_to_transformer(), test_to_transformer_list(), transformer_add_condition_information(), and update_cp_with_rhs_to_transformer().

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

◆ transformer_to_1D_lattice()

bool transformer_to_1D_lattice ( entity  v,
transformer  pre,
Value gcd_p,
Value c_p 
)

See if the equations in transformer "pre" constraint variable "v" by v = gcd x + c, where x is a free variable.

If "v" is free, gcd==1 and c==0

Entity "v" is supposed to represent a value

Returns true unless the equations in "pre" have no integer solutions.

Parameters
prere
gcd_pcd_p
c_p_p

Definition at line 2480 of file transformer.c.

2481 {
2483  Pbase b = sc_base(sc);
2484  bool success = true;
2485  // Default returned values
2486  *gcd_p = 1L;
2487  *c_p = 0L;
2488 
2489  if(base_contains_variable_p(b, (Variable) v)) {
2490  int rank = rank_of_variable(b, (Variable) v); // could be used in the test
2491  int n = sc_nbre_egalites(sc);
2492  if(n>0) {
2493  int m = base_dimension(sc_base(sc));
2494  Pmatrix A, B;
2495  A = matrix_new(n, m);
2496  B = matrix_new(n, 1);
2497  constraints_to_matrices(sc_egalites(sc), sc_base(sc), A, B);
2498  // A x + B = 0 is transformed into A x = B
2499  for(int i=1;i<=n;i++) MATRIX_ELEM(B, i, 1) = -MATRIX_ELEM(B, i, 1);
2500  if(!matrices_to_1D_lattice(A, B, n, m, rank, gcd_p, c_p)) {
2501  // The transformer is in fact empty because its diophantine
2502  // equations have no solution
2503  success = false;
2504  }
2505  free(A);
2506  free(B);
2507  }
2508  }
2509  return success;
2510 }
int rank_of_variable(Pbase base, Variable var)
this function returns the rank of the variable var in the base 0 encodes TCST, but I do not know why,...
Definition: base.c:497
#define A(i, j)
comp_matrice.c
Definition: comp_matrice.c:63
bool success
Definition: gpips-local.h:59
#define B(A)
Definition: iabrev.h:61
#define MATRIX_ELEM(matrix, i, j)
Macros d'acces aux elements d'une matrice.
Definition: matrix-local.h:80
Pmatrix matrix_new(int m, int n)
package matrix
Definition: alloc.c:41
int matrices_to_1D_lattice(Pmatrix, Pmatrix, int, int, int, Value *, Value *)
Under the assumption A x = B, A[n,m] and B[n], compute the 1-D lattice for x_i of x[m] as.
Definition: smith.c:195
static entity rank
void constraints_to_matrices(Pcontrainte, Pbase, Pmatrix, Pmatrix)
=======================================================================
Definition: pip__tab.h:25
Definition: pip__tab.h:30
package matrice
Definition: matrix-local.h:63

References A, B, base_contains_variable_p(), base_dimension, constraints_to_matrices(), free(), matrices_to_1D_lattice(), MATRIX_ELEM, matrix_new(), predicate_system, rank, rank_of_variable(), and transformer_relation.

Referenced by modulo_by_a_constant_to_transformer().

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

◆ transformer_to_analyzed_array_locations()

list transformer_to_analyzed_array_locations ( transformer  tf)
Parameters
tff

Definition at line 2776 of file transformer.c.

2777 {
2779 }
static list generic_transformer_to_analyzed_locations(transformer tf, bool array_p)
The list of location entities that appear in the basis of the transformer predicate.
Definition: transformer.c:2745

References generic_transformer_to_analyzed_locations().

Referenced by generic_substitute_formal_array_elements_in_transformer(), new_array_elements_backward_substitution_in_transformer(), and new_array_elements_forward_substitution_in_transformer().

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

◆ transformer_to_analyzed_arrays()

list transformer_to_analyzed_arrays ( transformer  tf)

The list of array entities that appear in the basis of the transformer predicate as array element locations.

Parameters
tff

Definition at line 2793 of file transformer.c.

2794 {
2795  list l = NIL;
2797  Pvecteur b = sc_base(sc), cb;
2798  for(cb=b; !VECTEUR_UNDEFINED_P(cb); cb = vecteur_succ(cb)) {
2799  Variable v = vecteur_var(cb);
2800  entity e = value_to_variable((entity) v);
2801  value val = entity_initial(e);
2802  //if(location_entity_p(e)) {
2803  if(value_reference_p(val)) {
2804  value val = entity_initial(e);
2805  reference r = value_reference(val);
2806  entity a = reference_variable(r);
2807  if(!gen_in_list_p(a, l))
2808  l = CONS(ENTITY, a, l);
2809  }
2810  }
2811  return l;
2812 }
#define value_reference(x)
Definition: ri.h:3085
#define value_reference_p(x)
Definition: ri.h:3083

References CONS, ENTITY, entity_initial, gen_in_list_p(), NIL, predicate_system, reference_variable, transformer_relation, value_reference, value_reference_p, value_to_variable(), vecteur_succ, VECTEUR_UNDEFINED_P, and vecteur_var.

Referenced by generic_substitute_formal_array_elements_in_transformer().

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

◆ transformer_to_analyzed_locations()

list transformer_to_analyzed_locations ( transformer  tf)

The list of location entities that appear in the basis of the transformer predicate.

Parameters
tff

Definition at line 2785 of file transformer.c.

2786 {
2788 }

References generic_transformer_to_analyzed_locations().

Referenced by substitute_stubs_in_transformer(), and substitute_stubs_in_transformer_with_translation_binding().

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

◆ transformer_to_domain()

transformer transformer_to_domain ( transformer  tf)

Return the domain of relation tf in a newly allocated transformer.

Projection of all new values of modified variables. Renaming of old values as new values. The transformer returned is a predicate on the input state (i.e. not really a transformer).

dtf = transformer_projection(dtf, args);

dtf = transformer_projection_with_redundancy_elimination(dtf, new_args, sc_identity);

The resulting transformer is going to be inconsistent because old values appear although the argument list is empty.

Careful, sc and b have been updated by the projections

A variable may be modified but its old value does not have to appear in the basis. Although the opposite is wrong.

Parameters
tff

Definition at line 772 of file transformer.c.

773 {
774  transformer dtf = transformer_dup(tf);
775  list new_args = NIL;
777  Pbase b = sc_base(sc);
778 
780  entity nv = entity_to_new_value(a);
781 
782  if(base_contains_variable_p(b, (Variable) nv)) {
783  new_args = CONS(ENTITY, nv, new_args);
784  }
785  }
786 
787  /* dtf = transformer_projection(dtf, args); */
788  /* dtf = transformer_projection_with_redundancy_elimination(dtf, new_args,
789  sc_identity); */
790  /* The resulting transformer is going to be inconsistent because old
791  values appear although the argument list is empty. */
792  dtf = transformer_projection_without_check(dtf, new_args,
793  sc_identity);
794 
795  /* Careful, sc and b have been updated by the projections */
797  b = sc_base(sc);
798 
799  FOREACH(ENTITY, a, new_args) {
800  entity ov = entity_to_old_value(a);
801  entity nv = entity_to_new_value(a);
802 
803  /* A variable may be modified but its old value does not have to
804  appear in the basis. Although the opposite is wrong. */
805  if(base_contains_variable_p(b, (Variable) ov)) {
806  dtf = transformer_value_substitute(dtf, ov, nv);
807  }
808  }
809 
810  gen_free_list(new_args);
811 
812  return dtf;
813 }
transformer transformer_projection_without_check(transformer t, list args, Psysteme(*elim)(Psysteme))
In some cases, you know the projection will result in a non-consistent transformer that will be fixed...
Definition: transformer.c:1334

References base_contains_variable_p(), CONS, ENTITY, entity_to_new_value(), entity_to_old_value(), FOREACH, gen_free_list(), NIL, predicate_system, sc_identity(), transformer_arguments, transformer_dup(), transformer_projection_without_check(), transformer_relation, and transformer_value_substitute().

Referenced by call_to_total_precondition(), loop_to_total_precondition(), transformer_combine(), and transformer_safe_domain().

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

◆ transformer_to_local_values()

list transformer_to_local_values ( transformer  tf,
list  dl 
)

Build a list of values appearing in tf that are linked to a variable in dl.

These values must be projected if the variables in dl are no longer in the scope, e.g. because they were declared in a block.

FI: I am not sure about what shuold be done for stubs

Parameters
tff
dll

Definition at line 2821 of file transformer.c.

2822 {
2823  list l = NIL;
2824  //entity m = get_current_module_entity();
2826  Pvecteur b = sc_base(sc), cb;
2827  for(cb=b; !VECTEUR_UNDEFINED_P(cb); cb = vecteur_succ(cb)) {
2828  Variable v = vecteur_var(cb);
2829  entity e = value_to_variable((entity) v);
2830  bool remove_p = false;
2831  if(gen_in_list_p(e, dl))
2832  remove_p = true;
2833  else {
2834  value val = entity_initial(e);
2835  if(value_reference_p(val)) {
2836  reference r = value_reference(val);
2837  e = reference_variable(r);
2838  if(gen_in_list_p(e, dl))
2839  remove_p = true;
2840  }
2841  }
2842  if(remove_p && !gen_in_list_p(v, l))
2843  l = CONS(ENTITY, v, l);
2844  }
2845  return l;
2846 }

References CONS, ENTITY, entity_initial, gen_in_list_p(), NIL, predicate_system, reference_variable, transformer_relation, value_reference, value_reference_p, value_to_variable(), vecteur_succ, VECTEUR_UNDEFINED_P, and vecteur_var.

Referenced by statement_to_transformer().

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

◆ transformer_to_potential_stub_translation()

list transformer_to_potential_stub_translation ( transformer  ,
entity   
)

◆ transformer_to_string()

string transformer_to_string ( transformer  tf)

prettyprint.c

Parameters
tff

Definition at line 52 of file prettyprint.c.

53 {
54  pips_internal_error("not implemenented anymore, tf=%p", tf);
55  return string_undefined;
56 }

References pips_internal_error, and string_undefined.

◆ transformer_value_substitutable_p()

bool transformer_value_substitutable_p ( transformer  t,
entity  e1,
entity  e2 
)

If e1 does not appear in t, it is substitutable.

If e1 does appear in t but not e2, again it is substitutable. Else, it if not.

Parameters
e11
e22

Definition at line 2033 of file transformer.c.

2034 {
2035  bool substitutable_p = true;
2037 
2038  pips_assert("e1 and e2 are defined entities",
2039  e1 != entity_undefined && e2 != entity_undefined);
2040 
2041  if(base_contains_variable_p(s->base, (Variable) e1)) {
2042  substitutable_p = !base_contains_variable_p(s->base, (Variable) e2);
2043  }
2044 
2045  return substitutable_p;
2046 }

References Ssysteme::base, base_contains_variable_p(), entity_undefined, pips_assert, predicate_system, and transformer_relation.

Referenced by translate_global_value().

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

◆ transformer_value_substitute()

transformer transformer_value_substitute ( transformer  t,
entity  e1,
entity  e2 
)

transformer transformer_value_substitute(transformer t, entity e1, entity e2): if e2 does not appear in t initially: replaces occurences of value e1 by value e2 in transformer t's arguments and relation fields; else error fi

"e2 must not appear in t initially": this is the general case; the second case may occur when procedure A calls B and C and when B and C share a global variable X which is not seen from A. A may contain relations between B:X and C:X... See hidden.f in Bugs or Validation...

updates are performed by side effects

update only if necessary

rename value e1 in argument a; e1 does not necessarily appear in a because it's not necessarily the new value of a modified variable

Parameters
e11
e22

Definition at line 1993 of file transformer.c.

1994 {
1995  /* updates are performed by side effects */
1996 
1997  cons * a = transformer_arguments(t);
1999 
2000  pips_assert("e1 and e2 are defined entities",
2001  e1 != entity_undefined && e2 != entity_undefined);
2002  /*
2003  pips_assert("transformer_value_substitute",
2004  !base_contains_variable_p(s->base, (Variable) e2));
2005  */
2006 
2007  /* update only if necessary */
2008  if(base_contains_variable_p(s->base, (Variable) e1)) {
2009 
2010  if(!base_contains_variable_p(s->base, (Variable) e2)) {
2011 
2012  (void) sc_variable_rename(s,(Variable) e1, (Variable)e2);
2013 
2014  /* rename value e1 in argument a; e1 does not necessarily
2015  appear in a because it's not necessarily the new value of
2016  a modified variable */
2017  MAPL(ce, {entity e = ENTITY(CAR(ce));
2018  if( e == e1) ENTITY_(CAR(ce)) = e2;},
2019  a);
2020  }
2021  else {
2022  pips_internal_error("cannot substitute e1=%s by e2=%s: e2 already in basis",
2023  entity_name(e1), entity_name(e2));
2024  }
2025  }
2026 
2027  return t;
2028 }
#define ENTITY_(x)
Definition: ri.h:2758

References Ssysteme::base, base_contains_variable_p(), CAR, ENTITY, ENTITY_, entity_name, entity_undefined, MAPL, pips_assert, pips_internal_error, predicate_system, sc_variable_rename(), transformer_arguments, and transformer_relation.

Referenced by add_type_information(), any_assign_operation_to_transformer(), any_scalar_assign_to_transformer_list(), any_scalar_assign_to_transformer_without_effect(), assigned_expression_to_transformer(), assigned_expression_to_transformer_list(), fortran_user_call_to_transformer(), perform_array_element_substitutions_in_transformer(), precondition_intra_to_inter(), substitute_scalar_stub_in_transformer(), substitute_stubs_in_transformer_with_translation_binding(), transformer_intersect_range_with_domain(), transformer_safe_value_substitute(), transformer_to_domain(), translate_global_value(), and value_passing_summary_transformer().

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

◆ transformer_variables_filter()

transformer transformer_variables_filter ( transformer  t,
list  vl 
)

Transformers are dealing with variables and/or variable values.

The confusion is magnified because the new value of a variable is often identified to the variable. Also, it is not 100% clear if the argument list of a transformer is a list of variables or a list of new values. In principle, it is a list of variables or locations. To make thisn worse, both value and variable start with a v...

Here, it is assumed that list vl is a list of variables or locations.

Transformer t is modified by side effect. All values linked to any variable in ist vl are projected, when possible. It is assumed that the projected variables are removed from the transformer argument.

Parameters
vll

Definition at line 1827 of file transformer.c.

1828 {
1829  list values = NIL;
1830  FOREACH(ENTITY, var, vl) {
1831  if(entity_has_values_p(var)) {
1832  entity new_val = entity_to_new_value(var);
1833  // FI it might be necessary to guard this definition
1834  entity old_val = entity_to_old_value(var);
1835  values = CONS(ENTITY, new_val, values);
1836  if(!entity_undefined_p(old_val))
1837  values = CONS(ENTITY, old_val, values);
1838  }
1839  }
1840  t = transformer_filter(t, values);
1841  gen_free_list(values);
1842  return t;
1843 }
transformer transformer_filter(transformer t, list args)
transformer transformer_filter(transformer t, cons * args): projection of t along the hyperplane defi...
Definition: transformer.c:1716

References CONS, ENTITY, entity_has_values_p(), entity_to_new_value(), entity_to_old_value(), entity_undefined_p, FOREACH, gen_free_list(), NIL, and transformer_filter().

+ Here is the call graph for this function:

◆ transformer_weak_consistency_p()

bool transformer_weak_consistency_p ( transformer  t)

Interprocedural transformers do not meet all conditions.

Definition at line 626 of file basic.c.

628 {
629  return transformer_general_consistency_p(t, true);
630 }

References transformer_general_consistency_p().

Referenced by c_user_call_to_transformer(), fortran_user_call_to_transformer(), transformer_filter(), transformer_formal_parameter_projection(), transformer_projection_with_redundancy_elimination_and_check(), and transformer_return_value_projection().

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

◆ transformer_with_temporary_values_p()

bool transformer_with_temporary_values_p ( transformer  tf)

Does transformer tf use temporary values?

Parameters
tff

Definition at line 1131 of file transformer.c.

1132 {
1133  int count = 0;
1134 
1135  if(number_of_temporary_values()>0) {
1137  Pbase b = BASE_NULLE;
1138 
1139  for(b = sc_base(r); !BASE_NULLE_P(b); b = vecteur_succ(b)) {
1140  entity e = (entity) vecteur_var(b);
1142  count++;
1143  }
1144  }
1145  }
1146  return count>0;
1147 }
static int count
Definition: SDG.c:519

References BASE_NULLE, BASE_NULLE_P, count, local_temporary_value_entity_p(), number_of_temporary_values(), predicate_system, transformer_relation, vecteur_succ, and vecteur_var.

+ Here is the call graph for this function:

◆ transformers_apply()

list transformers_apply ( list  tl,
transformer  pre 
)

Same as previous one, but with a more normalized name.

Parameters
tll
prere

Definition at line 1616 of file transformer.c.

1617 {
1618  return transformer_apply_generic(tl, pre, false);
1619 }

References transformer_apply_generic().

Referenced by transformer_list_closure_to_precondition_depth_two(), and transformer_list_closure_to_precondition_max_depth().

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

◆ transformers_apply_and_keep_all()

list transformers_apply_and_keep_all ( list  tl,
transformer  pre 
)

Same as previous one, but with a more normalized name.

Parameters
tll
prere

Definition at line 1622 of file transformer.c.

1623 {
1624  return transformer_apply_generic(tl, pre, true);
1625 }

References transformer_apply_generic().

Referenced by transformer_list_closure_to_precondition_depth_two(), and transformer_list_closure_to_precondition_max_depth().

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

◆ transformers_combine()

list transformers_combine ( list  tl1,
transformer  t2 
)

Combine each transformer of transformer list tl1 with t2.

Side-effect on tl1 or new list etl. See comments for transformer_combine()

FI: I'm not too sure about the best way to remove the resulting empty transformers. gen_remove() on tl1 or creation of new list...

Parameters
tl1l1
t22

Definition at line 454 of file transformer.c.

455 {
456  list ntl = NIL;
457 
458  FOREACH(TRANSFORMER, t1, tl1) {
459  t1 = transformer_combine(t1, t2);
460  if(!transformer_empty_p(t1))
461  ntl = gen_nconc(ntl, CONS(TRANSFORMER, t1, NIL));
462  }
463 
464  gen_free_list(tl1);
465  return ntl;
466 }

References CONS, FOREACH, gen_free_list(), gen_nconc(), NIL, TRANSFORMER, transformer_combine(), and transformer_empty_p().

Referenced by transformer_list_closure_to_precondition_depth_two(), and transformer_list_closure_to_precondition_max_depth().

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

◆ transformers_consistency_p()

bool transformers_consistency_p ( list  tl)
Parameters
tll

Definition at line 616 of file basic.c.

617 {
618  bool consistent_p = true;
619  FOREACH(TRANSFORMER, t, tl) {
620  consistent_p = consistent_p && transformer_general_consistency_p(t, false);
621  }
622  return consistent_p;
623 }

References FOREACH, TRANSFORMER, and transformer_general_consistency_p().

Referenced by safe_assigned_expression_to_transformer_list().

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

◆ transformers_derivative_fix_point()

list transformers_derivative_fix_point ( list  tl)
Parameters
tll

Definition at line 1262 of file fix_point.c.

1263 {
1264  list ntl = NIL;
1265  FOREACH(TRANSFORMER, tf, tl) {
1267  ntl = CONS(TRANSFORMER, fix_tf, ntl);
1268  }
1269  ntl = gen_nreverse(ntl);
1270  return ntl;
1271 }
transformer transformer_derivative_fix_point(transformer tf)
Computation of a transitive closure using constraints on the discrete derivative.
Definition: fix_point.c:1067

References CONS, FOREACH, gen_nreverse(), NIL, TRANSFORMER, and transformer_derivative_fix_point().

Referenced by transformer_list_closure_to_precondition_depth_two(), and transformer_list_closure_to_precondition_max_depth().

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

◆ transformers_range()

list transformers_range ( list  tfl)

Substitute each transformer in list tfl by its range.

Parameters
tflfl

Definition at line 754 of file transformer.c.

755 {
756  // The substitution in the list cannot be performed by a FOREACH
757  MAPL(ctf, {
758  transformer tf = TRANSFORMER(CAR(ctf));
759  transformer tfr = transformer_range(tf);
760  free_transformer(tf);
761  TRANSFORMER_(CAR(ctf)) = tfr;
762  }, tfl);
763  return tfl;
764 }
#define TRANSFORMER_(x)
Definition: ri.h:2844

References CAR, free_transformer(), MAPL, TRANSFORMER, TRANSFORMER_, and transformer_range().

Referenced by block_to_transformer_list().

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

◆ transformers_safe_apply()

list transformers_safe_apply ( list  tl,
transformer  pre 
)

returns a list of postconditions, one for each transformer in tl

Parameters
tll
prere

Definition at line 1638 of file transformer.c.

1639 {
1640  list postl = NIL;
1641  FOREACH(TRANSFORMER, tf, tl) {
1642  transformer post = transformer_safe_apply(tf, pre);
1643  postl = CONS(TRANSFORMER, post, postl);
1644  }
1645  postl = gen_nreverse(postl);
1646  return postl;
1647 }
transformer transformer_safe_apply(transformer tf, transformer pre)
Definition: transformer.c:1627

References CONS, FOREACH, gen_nreverse(), NIL, TRANSFORMER, and transformer_safe_apply().

Referenced by block_to_transformer_list().

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

◆ transformers_safe_normalize()

list transformers_safe_normalize ( list  tl,
int  level 
)
Parameters
tll
levelevel

Definition at line 1119 of file transformer.c.

1120 {
1121  list ntl = NIL;
1122  FOREACH(TRANSFORMER, tf, tl) {
1124  ntl = CONS(TRANSFORMER, ntf, ntl);
1125  }
1126  ntl = gen_nreverse(ntl);
1127  return ntl;
1128 }
transformer transformer_safe_normalize(transformer t, int level)
Definition: transformer.c:1111

References CONS, FOREACH, gen_nreverse(), level, NIL, TRANSFORMER, and transformer_safe_normalize().

Referenced by block_to_transformer_list().

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

◆ two_transformers_to_list()

list two_transformers_to_list ( transformer  t1,
transformer  t2 
)

Transformer two transformers into a correct transformer list.

Could be generalized to any number of transformers using a varargs... and more thinking.

Two transformers are obtained for loops that may be skipped or entered and for tests whose condition is not statically decidable.

This is a very dangerous step that should not always be taken. It is useful to ease the detection of identity paths, but it looses a lot of information. So almost identity path might simply be better identified elsewhere

Parameters
t11
t22

Definition at line 316 of file transformer_list.c.

317 {
318  list tl = NIL;
319  if(transformer_empty_p(t1)) {
320  if(transformer_empty_p(t2)) {
321  tl = NIL;
322  }
323  else {
324  tl = CONS(TRANSFORMER, t2, NIL);
325  }
326  }
327  else {
328  if(transformer_empty_p(t2)) {
329  tl = CONS(TRANSFORMER, t1, NIL);
330  }
331  else {
332 
333  /* This is a very dangerous step that should not always be
334  taken. It is useful to ease the detection of identity
335  paths, but it looses a lot of information. So almost
336  identity path might simply be better identified elsewhere */
337  /*
338  if(ENDP(transformer_arguments(t1))) {
339  free_transformer(t1);
340  t1 = transformer_identity();
341  }
342 
343  if(ENDP(transformer_arguments(t2))) {
344  free_transformer(t2);
345  t2 = transformer_identity();
346  }
347  */
348 
349  if(transformer_identity_p(t1)) {
350  if(transformer_identity_p(t2)) {
351  tl = CONS(TRANSFORMER, t1, NIL);
352  free_transformer(t2);
353  }
354  else {
355  tl = CONS(TRANSFORMER, t1,
356  CONS(TRANSFORMER, t2, NIL));
357  }
358  }
359  else {
360  if(transformer_identity_p(t2)) {
361  tl = CONS(TRANSFORMER, t2,
362  CONS(TRANSFORMER, t1, NIL));
363  }
364  else {
365  tl = CONS(TRANSFORMER, t1,
366  CONS(TRANSFORMER, t2, NIL));
367  }
368  }
369  }
370  }
371  return tl;
372 }

References CONS, free_transformer(), NIL, TRANSFORMER, transformer_empty_p(), and transformer_identity_p().

Referenced by complete_any_loop_transformer_list(), and complete_repeatloop_transformer_list().

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

◆ type_to_sizeof_value()

entity type_to_sizeof_value ( type  t)

Definition at line 899 of file value.c.

900 {
901  entity i;
902  if((i = (entity) hash_get(hash_type_to_sizeof_value, (char *) t))
903  == entity_undefined)
904  pips_internal_error("unbounded type %s : %s",
906  return i;
907 }

References entity_undefined, hash_get(), hash_type_to_sizeof_value, pips_internal_error, type_to_full_string_definition(), and type_to_string().

Referenced by expression_multiply_sizeof_to_transformer().

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

◆ value_alias()

entity value_alias ( entity  e)

Static aliasing.

useful for Fortran, useless for C. When no alias is found, an undefined entity must be returned.

lookup the current value name mapping and return an arbitrary "representant" of the interprocedural alias set of e; the equivalence relation is "has same location"

Definition at line 1729 of file value.c.

1730 {
1732 
1733  pips_debug(8,"begin: for %s\n", entity_name(e));
1734 
1735  /* lookup the current value name mapping and return an arbitrary "representant"
1736  of the interprocedural alias set of e; the equivalence relation is "has
1737  same location" */
1738  HASH_FOREACH(entity, var, string, val, hash_value_to_name) {
1739  if(variable_entity_p(var)
1740  && entities_may_conflict_p(var, e)) {
1741  a = var;
1742  break;
1743  }
1744  }
1745 
1746  if(a==entity_undefined)
1747  pips_debug(8, "return: %s\n", "entity_undefined");
1748  else
1749  pips_debug(8, "return: %s\n", entity_name(a));
1750 
1751  return a;
1752 }
#define HASH_FOREACH(key_type, k, value_type, v, ht)
Definition: newgen_hash.h:71
bool variable_entity_p(entity)
variable.c
Definition: variable.c:70

References entities_may_conflict_p(), entity_name, entity_undefined, HASH_FOREACH, hash_value_to_name, pips_debug, and variable_entity_p().

Referenced by add_interprocedural_new_value_entity(), add_interprocedural_value_entities(), and translate_global_value().

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

◆ value_belongs_to_transformer_space()

bool value_belongs_to_transformer_space ( entity  v,
transformer  tf 
)
Parameters
tff

Definition at line 842 of file basic.c.

843 {
845  Pbase b = BASE_UNDEFINED;
846  bool found_p = false;
847 
848  for(b=sc_base(sc); !BASE_NULLE_P(b); b = vecteur_succ(b)) {
849  entity bv = (entity) vecteur_var(b);
850 
851  if(bv==v) {
852  found_p = true;
853  break;
854  }
855  }
856  return found_p;
857 }

References BASE_NULLE_P, BASE_UNDEFINED, predicate_system, transformer_relation, vecteur_succ, and vecteur_var.

Referenced by transformer_add_variable_type_information().

+ Here is the caller graph for this function:

◆ value_entity_p()

bool value_entity_p ( entity  e)

tells if e is seen as a variable value in the current module

Definition at line 976 of file value.c.

977 {
978  /* tells if e is seen as a variable value in the current module */
979  string s = hash_get(hash_value_to_name, (char *) e);
980 
981  if(s == (char*) HASH_UNDEFINED_VALUE) {
982  return false;
983  }
984  else {
985  return true;
986  }
987 }

References hash_get(), HASH_UNDEFINED_VALUE, and hash_value_to_name.

Referenced by generic_value_name(), transformer_add_sign_information(), transformer_filter_subsumed_variables(), and translate_global_value().

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

◆ value_full_name()

string value_full_name ( entity  v)

for debugging purposes

Definition at line 1762 of file value.c.

1763 {
1764  return entity_name(v);
1765 }

References entity_name.

Referenced by parametric_transformer_empty_p().

+ Here is the caller graph for this function:

◆ value_to_variable()

entity value_to_variable ( entity  val)

Get the primitive variable associated to any value involved in a transformer.

For example can associate values such as "o#0" to "i" (via "i#init").

This function used to be restricted to values seen by the current module. It was extended to values in general to cope with translation issues.

for gcc only!

pips_assert("value_to_variable", s != HASH_UNDEFINED_VALUE);

pips_assert("value_to_variable", strchr(entity_name(val), (int) SEMANTICS_SEPARATOR) != NULL);

this may be a value, but it is unknown in the current module

new values in fact have no suffixes...

It can be an equivalenced variable... Additional testing should be performed!

Parameters
valal

Definition at line 1624 of file value.c.

1625 {
1626  entity var = entity_undefined;
1627  int l_suffix = -1; /* for gcc only! */
1628  string s = hash_get(hash_value_to_name, (char *) val);
1629  string var_name;
1630 
1631  /* pips_assert("value_to_variable", s != HASH_UNDEFINED_VALUE); */
1632 
1633  /* pips_assert("value_to_variable",
1634  strchr(entity_name(val), (int) SEMANTICS_SEPARATOR) != NULL); */
1635 
1636  // TODO : Maybe redesign the search of suffix/prefix
1637  // Can bug if the variable name is/begin/end with
1638  // o, i, t, new, init, int, address_of see SUFFIX and PREFIX in transformer.h
1639  if(s == HASH_UNDEFINED_VALUE) {
1640  /* this may be a value, but it is unknown in the current module */
1641  string val_name = entity_name(val);
1642 
1643  if(strstr(val_name, NEW_VALUE_SUFFIX) != NULL)
1644  l_suffix = strlen(NEW_VALUE_SUFFIX);
1645  else if(strstr(val_name, OLD_VALUE_SUFFIX) != NULL)
1646  l_suffix = strlen(OLD_VALUE_SUFFIX);
1647  else if(strstr(val_name, INTERMEDIATE_VALUE_SUFFIX) != NULL)
1648  l_suffix = strlen(INTERMEDIATE_VALUE_SUFFIX);
1649  else if(strstr(val_name, ADDRESS_OF_SUFFIX) != NULL)
1650  l_suffix = strlen(ADDRESS_OF_SUFFIX);
1651  else if(strstr(val_name, SIZEOF_SUFFIX) != NULL)
1652  l_suffix = 0;
1653  else if(strchr(val_name, (int) SEMANTICS_SEPARATOR) == NULL) {
1654  /* new values in fact have no suffixes... */
1655  l_suffix = 0;
1656  }
1657  else
1658  pips_internal_error("%s is not a non-local value", entity_name(val));
1659 
1660  s = val_name;
1661  }
1662  else {
1663  if(sizeof_value_entity_p(val))
1664  l_suffix = 0;
1665  else if(new_value_entity_p(val))
1666  l_suffix = strlen(NEW_VALUE_SUFFIX);
1667  else if(old_value_entity_p(val))
1668  l_suffix = strlen(OLD_VALUE_SUFFIX);
1669  else if(intermediate_value_entity_p(val))
1670  l_suffix = strlen(INTERMEDIATE_VALUE_SUFFIX);
1671  else if(address_of_value_entity_p(val))
1672  l_suffix = strlen(ADDRESS_OF_SUFFIX);
1673  else
1674  /* It can be an equivalenced variable... Additional testing
1675  should be performed! */
1676  pips_internal_error("%s is not a locally visible value",
1677  entity_name(val));
1678  }
1679 
1680  var_name = strdup(s);
1681  *(var_name+strlen(var_name)-l_suffix) = '\0';
1682  if(address_of_value_entity_p(val)) {
1683  string temp = strstr(var_name, "[");
1684  if(temp != NULL)
1685  *temp = '\0';
1686  }
1687 
1688  var = gen_find_tabulated(var_name, entity_domain);
1689  free(var_name);
1690 
1691  if( var == entity_undefined )
1692  pips_internal_error("no related variable for val=%s",
1693  entity_name(val));
1694 
1695  return var;
1696 }
bool new_value_entity_p(entity e)
the following three functions are directly or indirectly relative to the current module and its value...
Definition: value.c:925
bool intermediate_value_entity_p(entity e)
Definition: value.c:955
bool old_value_entity_p(entity e)
Definition: value.c:936

References ADDRESS_OF_SUFFIX, address_of_value_entity_p(), entity_domain, entity_name, entity_undefined, free(), gen_find_tabulated(), hash_get(), HASH_UNDEFINED_VALUE, hash_value_to_name, intermediate_value_entity_p(), INTERMEDIATE_VALUE_SUFFIX, new_value_entity_p(), NEW_VALUE_SUFFIX, old_value_entity_p(), OLD_VALUE_SUFFIX, pips_internal_error, SEMANTICS_SEPARATOR, SIZEOF_SUFFIX, sizeof_value_entity_p(), and strdup().

Referenced by add_address_of_value(), add_loop_index_exit_value(), add_type_information(), any_assign_operation_to_transformer(), any_scalar_assign_to_transformer_list(), any_scalar_assign_to_transformer_without_effect(), fortran_user_call_to_transformer(), generic_transformer_intra_to_inter(), generic_transformer_to_analyzed_locations(), invariant_vector_p(), look_for_the_best_counter(), old_value_to_new_value(), pips_user_value_name(), print_call_precondition(), transformer_add_variable_incrementation(), transformer_add_variable_update(), transformer_derivative_constraints(), transformer_derivative_fix_point(), transformer_formal_parameter_projection(), transformer_general_consistency_p(), transformer_list_generic_transitive_closure(), transformer_projection_with_redundancy_elimination_and_check(), transformer_return_value_projection(), transformer_to_analyzed_arrays(), transformer_to_local_values(), transformer_to_potential_stub_translation(), and value_passing_summary_transformer().

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

◆ vect_variables_to_values()

Pvecteur vect_variables_to_values ( Pvecteur  v)

FI: not used, not debugged.

Definition at line 1755 of file value.c.

1756 {
1758  return v;
1759 }
Pvecteur vect_rename_variables(Pvecteur v, bool(*renamed_p)(Variable), Variable(*new_variable)(Variable))
Pvecteur vect_rename_variables(v, renamed_p, new_variable) Pvecteur v; bool (*renamed_p)(Variable); V...
Definition: base.c:281
static bool non_local_temporary_value_entity_p(entity e)
Definition: value.c:660

References entity_to_new_value(), non_local_temporary_value_entity_p(), and vect_rename_variables().

+ Here is the call graph for this function:

Variable Documentation

◆ transformer_fix_point_operator

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

fix_point.c

fix_point.c

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.