PIPS
transformer.c File Reference
#include <stdio.h>
#include "linear.h"
#include "matrice.h"
#include "sparse_sc.h"
#include "genC.h"
#include "ri.h"
#include "ri-util.h"
#include "effects-util.h"
#include "prettyprint.h"
#include "misc.h"
#include "transformer.h"
+ Include dependency graph for transformer.c:

Go to the source code of this file.

Functions

static Psysteme sc_identity (Psysteme sc)
 Predicate transformer package: sc complexity level. More...
 
transformer simple_equality_to_transformer (entity e, entity f, bool assignment)
 e and f are assumed to be values, Type independent. More...
 
transformer simple_unary_minus_to_transformer (entity e, entity f)
 
transformer generic_equality_to_transformer (entity e, entity f, bool assignment, bool unary_minus_p)
 
transformer simple_addition_to_transformer (entity e, entity e1, entity e2, bool addition_p)
 e and e1 and e2 are assumed to be values. More...
 
transformer relation_to_transformer (entity op, entity e1, entity e2, bool veracity)
 e and f are assumed to be values. More...
 
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) More...
 
list transformers_combine (list tl1, transformer t2)
 Combine each transformer of transformer list tl1 with t2. More...
 
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. More...
 
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. More...
 
static transformer transformer_general_intersection (transformer t1, transformer t2, bool image_only)
 Allocate a new transformer with constraints in t1 and t2. More...
 
transformer transformer_intersection (transformer t1, transformer t2)
 tf is a new transformer that receives the constraints in t1 and t2. More...
 
transformer transformer_image_intersection (transformer t1, transformer t2)
 allocate a new transformer based on transformer t1 and postcondition t2 More...
 
static transformer transformer_safe_general_intersection (transformer t1, transformer t2, bool image_only)
 Allocate a new transformer. More...
 
transformer transformer_safe_intersection (transformer t1, transformer t2)
 Allocate a new transformer. More...
 
transformer transformer_safe_image_intersection (transformer t1, transformer t2)
 Allocate a new transformer. More...
 
transformer transformer_domain_intersection (transformer tf, transformer pre)
 Restrict the domain of the relation tf with pre. More...
 
transformer transformer_safe_domain_intersection (transformer tf, transformer pre)
 If tf and pre are defined, update tf. More...
 
transformer transformer_range (transformer tf)
 Return the range of relation tf in a newly allocated transformer. More...
 
transformer transformer_safe_range (transformer tf)
 
list transformers_range (list tfl)
 Substitute each transformer in list tfl by its range. More...
 
transformer transformer_to_domain (transformer tf)
 Return the domain of relation tf in a newly allocated transformer. More...
 
transformer transformer_safe_domain (transformer tf)
 
transformer transformer_range_intersection (transformer tf, transformer r)
 Allocate a new transformer rtf that is tf with its range restricted by the range r. More...
 
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. More...
 
static int varval_value_name_is_inferior_p (Pvecteur *pvarval1, Pvecteur *pvarval2)
 
transformer transformer_normalize (transformer t, int level)
 Eliminate (some) rational or integer redundancy. More...
 
transformer transformer_safe_normalize (transformer t, int level)
 
list transformers_safe_normalize (list tl, int level)
 
bool transformer_with_temporary_values_p (transformer tf)
 Does transformer tf use temporary values? More...
 
transformer transformer_temporary_value_projection (transformer tf)
 
transformer safe_transformer_projection (transformer t, list args)
 t may be undefined, args may contain values unrelated to t More...
 
transformer transformer_return_value_projection (entity f, transformer t)
 Project return values that are not linked to function f. More...
 
transformer transformer_projection (transformer t, list args)
 values in args must be in t's base More...
 
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 More...
 
Psysteme no_elim (Psysteme ps)
 
transformer transformer_projection_with_redundancy_elimination (transformer t, list args, Psysteme(*elim)(Psysteme))
 It is not clear if this function projects values or variables. More...
 
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 later. More...
 
transformer transformer_projection_with_redundancy_elimination_and_check (volatile transformer t, list args, Psysteme(*elim)(Psysteme), bool check_consistency_p)
 
transformer transformer_apply (transformer tf, transformer pre)
 transformer transformer_apply(transformer tf, transformer pre): apply transformer tf on precondition pre to obtain postcondition post More...
 
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. More...
 
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. More...
 
list transformers_apply (list tl, transformer pre)
 Same as previous one, but with a more normalized name. More...
 
list transformers_apply_and_keep_all (list tl, transformer pre)
 Same as previous one, but with a more normalized name. More...
 
transformer transformer_safe_apply (transformer tf, transformer pre)
 
list transformers_safe_apply (list tl, transformer pre)
 returns a list of postconditions, one for each transformer in tl More...
 
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 More...
 
transformer transformer_safe_inverse_apply (transformer tf, transformer post)
 
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; More...
 
transformer transformer_variables_filter (transformer t, list vl)
 Transformers are dealing with variables and/or variable values. More...
 
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. More...
 
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. More...
 
bool transformer_safe_affect_transformer_p (transformer tf1, transformer tf2)
 
transformer args_to_transformer (list le)
 Generates a transformer abstracting a totally unknown modification of the values associated to variables in list le. More...
 
transformer invariant_wrt_transformer (transformer p, transformer tf)
 transformer invariant_wrt_transformer(transformer p, transformer tf): Assume that tf is a fix-point operator. More...
 
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 More...
 
bool transformer_value_substitutable_p (transformer t, entity e1, entity e2)
 If e1 does not appear in t, it is substitutable. More...
 
transformer transformer_safe_value_substitute (transformer t, entity e1, entity e2)
 
Pvecteur simplify_float_constraint (Pvecteur v, bool is_equation_p)
 If v is a not a float constraint, retun v. More...
 
Psysteme simplify_float_constraint_system (Psysteme ps)
 Simplify float constraints and possibly detect. More...
 
static bool constant_constraint_check (Pvecteur v, bool is_equation_p)
 Check if a transformer is empty. More...
 
static bool parametric_transformer_empty_p (transformer t, Psysteme(*normalize)(Psysteme, char *(*)(Variable)))
 If true is returned, the transformer certainly is empty. More...
 
bool transformer_empty_p (transformer t)
 If true is returned, the transformer certainly is empty. More...
 
bool transformer_strongly_empty_p (transformer t)
 If true is returned, the transformer certainly is empty. More...
 
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. More...
 
static list entity_to_formal_integer_parameters (entity f)
 get unsorted list of formal integer parameters of module f by declaration filtering; these parameters may not be used by the callee's semantics analysis, but we have no way to know it because value mappings are not available. More...
 
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 More...
 
static bool expression_equal_in_context_p (expression e1, expression e2, transformer context)
 Fast checks : More...
 
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. More...
 
list transformer_to_potential_stub_translation (transformer tf, entity m __attribute__((unused)))
 Provide a list of variables that might be forward translated into a stub when preconditions are propagated in callees. More...
 
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. More...
 
list transformer_to_analyzed_array_locations (transformer tf)
 
list transformer_to_analyzed_locations (transformer tf)
 The list of location entities that appear in the basis of the transformer predicate. More...
 
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. More...
 
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. More...
 

Function Documentation

◆ 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 ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define transformer_relation(x)
Definition: ri.h:2873
#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
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
entity entity_to_new_value(entity)
Definition: value.c:859
#define VECTEUR_NUL
DEFINITION DU VECTEUR NUL.
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 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:

◆ constant_constraint_check()

static bool constant_constraint_check ( Pvecteur  v,
bool  is_equation_p 
)
static

Check if a transformer is empty.

Take into account, if necessary, constraints with floating point and string constraints. Simplify constraints build with float and string constants only

Logical are represented by integer values

PIPS does not represent negative constants: call to unary_minus

s1 = module_local_name(e);

s2 = module_local_name(e);

PIPS does not represent complex constants: call to CMPLX

Unfeasible equation or trivial inequality

Must be a trivial integer constraint. Already processed

Definition at line 2183 of file transformer.c.

2184 {
2185  string s1 = string_undefined;
2186  int i1 = 0;
2187  string s2 = string_undefined;
2188  int i2 = 0;
2189  double x = 0.;
2190  bool is_string = false;
2191  bool is_float = false;
2192  bool type_undecided_p = true;
2194  bool is_checked = true;
2195  int number_of_strings = 0;
2196 
2197  for(cv=v; !VECTEUR_UNDEFINED_P(cv); cv = vecteur_succ(cv)) {
2198  entity e = (entity) vecteur_var(cv);
2199  Value val = vecteur_val(cv);
2200 
2201  pips_assert("e is a constant", (Variable) e == TCST || entity_constant_p(e));
2202 
2203  if((Variable) e!=TCST) {
2204  basic b = constant_basic(e);
2205 
2206  switch(basic_tag(b)) {
2207  case is_basic_int:
2208  case is_basic_logical:
2209  /* Logical are represented by integer values*/
2210  pips_internal_error("Unexpected integer or logical type for constant %s",
2211  entity_name(e));
2212  break;
2213  case is_basic_float:
2214  /* PIPS does not represent negative constants: call to unary_minus */
2215  if(type_undecided_p) {
2216  type_undecided_p = false;
2217  is_float = true;
2218  }
2219  else {
2220  if(is_string) {
2221  pips_internal_error("String constant mixed up with float constant %s",
2222  entity_name(e));
2223  }
2224  }
2225  x = x + ((double) val) * float_constant_to_double(e);
2226  break;
2227  case is_basic_string:
2228  if(type_undecided_p) {
2229  type_undecided_p = false;
2230  is_string = true;
2231  }
2232  else {
2233  if(is_float) {
2234  pips_internal_error("Float constant mixed up with string constant %s",
2235  entity_name(e));
2236  }
2237  }
2238  if(number_of_strings==0) {
2239  /* s1 = module_local_name(e); */
2240  s1 = entity_name(e);
2241  i1 = (int) val;
2242  }
2243  else if(number_of_strings==1) {
2244  /* s2 = module_local_name(e); */
2245  s2 = entity_name(e);
2246  i2 = (int) val;
2247  }
2248  else
2249  pips_internal_error("Too many strings in a string constraint");
2250 
2251  number_of_strings++;
2252  break;
2253  case is_basic_complex:
2254  /* PIPS does not represent complex constants: call to CMPLX */
2255  pips_internal_error("Unexpected complex type for constant %s",
2256  entity_name(e));
2257  break;
2258  case is_basic_overloaded:
2259  pips_internal_error("Unexpected overloaded type for constant %s",
2260  entity_name(e));
2261  break;
2262  default:
2263  pips_internal_error("unknown basic b=%d", basic_tag(b));
2264  }
2265  }
2266  else {
2267  if(vect_size(v)==1) {
2268  /* Unfeasible equation or trivial inequality */
2269  is_checked = (is_equation_p ? false : (val <= 0));
2270  }
2271  else {
2272  pips_internal_error("Unexpected integer constant mixed up with "
2273  "non-integer constants\n");
2274  }
2275  }
2276  }
2277 
2278  pips_assert("It can't be a float and a string simultaneously",
2279  !(is_float && is_string));
2280 
2281  if(is_string) {
2282  if(number_of_strings!=2)
2283  pips_internal_error("Illegal number of strings in string constraint");
2284  if(is_equation_p) {
2285  if(i1+i2==0)
2286  is_checked = (fortran_string_compare(s1, s2)==0);
2287  else
2288  pips_internal_error("Unexpected string coefficients i1=%d, i2=%d for equality",
2289  i1, i2);
2290  }
2291  else {
2292  if(i1>0 && i1+i2==0)
2293  is_checked = (fortran_string_compare(s1, s2) <= 0);
2294  else if(i1<0 && i1+i2==0)
2295  is_checked = (fortran_string_compare(s1, s2) >= 0);
2296  else
2297  pips_internal_error("Unexpected string coefficients i1=%d, i2=%d for inequality",
2298  i1, i2);
2299  }
2300  }
2301  else if(is_float) {
2302  if(is_equation_p)
2303  is_checked = (x==0.);
2304  else
2305  is_checked = (x<0.);
2306  }
2307  else {
2308  /* Must be a trivial integer constraint. Already processed*/
2309  ;
2310  }
2311 
2312  return is_checked;
2313 }
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
void const char const char const int
int Value
double float_constant_to_double(entity c)
Definition: constant.c:639
basic constant_basic(entity c)
Definition: constant.c:633
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_internal_error
Definition: misc-local.h:149
#define string_undefined
Definition: newgen_types.h:40
#define false
Definition: newgen_types.h:80
#define entity_constant_p(e)
int fortran_string_compare(string fs1, string fs2)
compare pips fortran string constants from the fortran point of view.
Definition: expression.c:101
@ is_basic_string
Definition: ri.h:576
@ is_basic_float
Definition: ri.h:572
@ is_basic_overloaded
Definition: ri.h:574
@ is_basic_int
Definition: ri.h:571
@ is_basic_logical
Definition: ri.h:573
@ is_basic_complex
Definition: ri.h:575
#define basic_tag(x)
Definition: ri.h:613
#define entity_name(x)
Definition: ri.h:2790
s1
Definition: set.c:247
static char * x
Definition: split_file.c:159
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define vecteur_val(v)
#define vecteur_var(v)
#define VECTEUR_UNDEFINED
#define vecteur_succ(v)
#define VECTEUR_UNDEFINED_P(v)

References basic_tag, constant_basic(), entity_constant_p, entity_name, false, float_constant_to_double(), fortran_string_compare(), int, is_basic_complex, is_basic_float, is_basic_int, is_basic_logical, is_basic_overloaded, is_basic_string, pips_assert, pips_internal_error, s1, string_undefined, TCST, vect_size(), vecteur_succ, VECTEUR_UNDEFINED, VECTEUR_UNDEFINED_P, vecteur_val, vecteur_var, and x.

Referenced by parametric_transformer_empty_p().

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

◆ entity_to_formal_integer_parameters()

static list entity_to_formal_integer_parameters ( entity  f)
static

get unsorted list of formal integer parameters of module f by declaration filtering; these parameters may not be used by the callee's semantics analysis, but we have no way to know it because value mappings are not available.

Definition at line 2517 of file transformer.c.

2518 {
2519 
2520  list formals = NIL;
2521 
2522  pips_assert("entity is a module", entity_module_p(f));
2523 
2525  {
2528  formals = CONS(ENTITY, e, formals);
2529  }
2530 
2531  return formals;
2532 }
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
code entity_code(entity e)
Definition: entity.c:1098
bool entity_module_p(entity e)
Definition: entity.c:683
bool entity_integer_scalar_p(entity)
for variables (like I), not constants (like 1)! use integer_constant_p() for constants
Definition: variable.c:1130
#define storage_formal_p(x)
Definition: ri.h:2522
#define entity_storage(x)
Definition: ri.h:2794
#define code_declarations(x)
Definition: ri.h:784

References code_declarations, CONS, ENTITY, entity_code(), entity_integer_scalar_p(), entity_module_p(), entity_storage, f(), FOREACH, NIL, pips_assert, and storage_formal_p.

Referenced by formal_and_actual_parameters_association().

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

◆ expression_equal_in_context_p()

static bool expression_equal_in_context_p ( expression  e1,
expression  e2,
transformer  context 
)
static

Fast checks :

  • e1 and e2 are same expressions
  • e1 and e2 are equivalent because they are same common variables Slow check: If NOT(e1=e2) + prec = infeasible, we have e1=e2 is always true

Definition at line 2600 of file transformer.c.

2602 {
2603  normalized n1, n2;
2604  if (same_expression_p(e1,e2)) return true;
2606  {
2607  reference ref1 = expression_reference(e1);
2608  reference ref2 = expression_reference(e2);
2609  entity en1 = reference_variable(ref1);
2610  entity en2 = reference_variable(ref2);
2611  if (same_scalar_location_p(en1, en2)) return true;
2612  }
2615  n1 = NORMALIZE_EXPRESSION(e1);
2616  n2 = NORMALIZE_EXPRESSION(e2);
2617  ifdebug(4)
2618  {
2619  fprintf(stderr, "\n First expression : ");
2620  print_expression(e1);
2621  fprintf(stderr, "\n Second expression : ");
2622  print_expression(e2);
2623  fprintf(stderr, " \n equal in the context ?");
2625  }
2627  {
2628  Pvecteur v1 = normalized_linear(n1), v2 = normalized_linear(n2);
2629  Pvecteur v_init = vect_substract(v1, v2);
2630  // Trivial test e1=N+M, e2=M+N => e1=e2.
2631  // This test may be subsumed by the above test same_expression_p()
2632  if (vect_constant_p(v_init))
2633  {
2634  // Tets if v_init == 0
2635  if (VECTEUR_NUL_P(v_init)) return true;
2636  if (value_zero_p(val_of(v_init))) return true;
2637  if (value_notzero_p(val_of(v_init))) return false;
2638  }
2639  else
2640  {
2641  Pvecteur v_one = vect_new(TCST,1);
2642  Pvecteur v_not_e = vect_add(v_init,v_one);
2643  Pvecteur v_temp = vect_multiply(v_init,-1);
2644  Pvecteur v_not_e_2 = vect_add(v_temp,v_one);
2646  if (!efficient_sc_check_inequality_feasibility(v_not_e,ps) &&
2648  {
2649  vect_rm(v_one);
2650  return true;
2651  }
2652  vect_rm(v_one);
2653  }
2654  }
2655  return false;
2656 }
#define value_notzero_p(val)
#define value_zero_p(val)
bool vect_constant_p(Pvecteur)
bool vect_constant_p(Pvecteur v): v contains only a constant term, may be zero
Definition: predicats.c:211
transformer fprint_transformer(FILE *fd, transformer tf, get_variable_name_t value_name)
Definition: io.c:69
void print_expression(expression e)
no file descriptor is passed to make is easier to use in a debugging stage.
Definition: expression.c:58
#define NORMALIZE_EXPRESSION(e)
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
void clean_all_normalized(expression e)
Definition: expression.c:4102
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
bool 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
bool same_scalar_location_p(entity, entity)
FI: transferred from semantics (should be used for effect translation as well)
Definition: variable.c:1992
#define normalized_linear_p(x)
Definition: ri.h:1779
#define reference_variable(x)
Definition: ri.h:2326
#define normalized_linear(x)
Definition: ri.h:1781
#define predicate_system(x)
Definition: ri.h:2069
bool efficient_sc_check_inequality_feasibility(Pvecteur v, Psysteme prec)
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
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 ifdebug(n)
Definition: sg.c:47
Definition: delay.c:253
#define val_of(varval)
char *(* get_variable_name_t)(Variable)
Definition: vecteur-local.h:62
#define VECTEUR_NUL_P(v)
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
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78
Pvecteur vect_add(Pvecteur v1, Pvecteur v2)
package vecteur - operations binaires
Definition: binaires.c:53
Pvecteur vect_substract(Pvecteur v1, Pvecteur v2)
Pvecteur vect_substract(Pvecteur v1, Pvecteur v2): allocation d'un vecteur v dont la valeur est la di...
Definition: binaires.c:75

References clean_all_normalized(), efficient_sc_check_inequality_feasibility(), entity_local_name(), expression_reference(), expression_reference_p(), fprint_transformer(), fprintf(), ifdebug, NORMALIZE_EXPRESSION, normalized_linear, normalized_linear_p, predicate_system, print_expression(), reference_variable, same_expression_p(), same_scalar_location_p(), TCST, transformer_relation, val_of, value_notzero_p, value_zero_p, vect_add(), vect_constant_p(), vect_multiply(), vect_new(), vect_rm(), vect_substract(), and VECTEUR_NUL_P.

Referenced by same_dimension_p().

+ Here is the call graph for this function:
+ 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 ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#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
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
expression find_ith_argument(list args, int n)
Definition: expression.c:1147
#define formal_offset(x)
Definition: ri.h:1408
#define transformer_undefined
Definition: ri.h:2847
#define call_function(x)
Definition: ri.h:709
#define storage_formal(x)
Definition: ri.h:2524
#define expression_undefined
Definition: ri.h:1223
#define call_arguments(x)
Definition: ri.h:711
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:

◆ 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
predicate make_predicate(Psysteme a1)
Definition: ri.c:1820
#define VALUE_MONE
#define VALUE_ONE
#define CONTRAINTE_UNDEFINED
Pcontrainte contrainte_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
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
Pcontrainte eq
element du vecteur colonne du systeme donne par l'analyse
Definition: sc_gram.c:108

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_to_analyzed_locations()

static list generic_transformer_to_analyzed_locations ( transformer  tf,
bool  array_p 
)
static

The list of location entities that appear in the basis of the transformer predicate.

Definition at line 2745 of file transformer.c.

2746 {
2747  list l = NIL;
2748  //entity m = get_current_module_entity();
2750  Pvecteur b = sc_base(sc), cb;
2751  for(cb=b; !VECTEUR_UNDEFINED_P(cb); cb = vecteur_succ(cb)) {
2752  Variable v = vecteur_var(cb);
2754  entity e = value_to_variable((entity) v);
2755  value val = entity_initial(e);
2756  //if(location_entity_p(e)) {
2757  if(value_reference_p(val)) {
2758  // The test is not needed beause of the basis property: each
2759  // dimension is unique. But value_to_variable() is a
2760  // many-to-one mapping
2761 
2762  if(!gen_in_list_p(e, l))
2763  l = CONS(ENTITY, e, l);
2764  }
2765  // FI: m should be the callee and it is the caller
2766  //else if(!array_p && stub_entity_of_module_p(e, m)) {
2767  else if(!array_p && entity_stub_sink_p(e)) {
2768  if(!gen_in_list_p(e, l))
2769  l = CONS(ENTITY, e, l);
2770  }
2771  }
2772  }
2773  return l;
2774 }
bool entity_stub_sink_p(entity e)
test if an entity is a stub sink for a formal parameter e.g.
bool gen_in_list_p(const void *vo, const list lx)
tell whether vo belongs to lx
Definition: list.c:734
#define value_reference_p(x)
Definition: ri.h:3083
#define entity_initial(x)
Definition: ri.h:2796
bool local_temporary_value_entity_p(entity)
Definition: value.c:654
entity value_to_variable(entity)
Get the primitive variable associated to any value involved in a transformer.
Definition: value.c:1624

References CONS, ENTITY, entity_initial, entity_stub_sink_p(), gen_in_list_p(), local_temporary_value_entity_p(), NIL, predicate_system, transformer_relation, value_reference_p, value_to_variable(), vecteur_succ, VECTEUR_UNDEFINED_P, and vecteur_var.

Referenced by transformer_to_analyzed_array_locations(), and transformer_to_analyzed_locations().

+ 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
#define transformer_undefined_p(x)
Definition: ri.h:2848
transformer args_to_transformer(list le)
Generates a transformer abstracting a totally unknown modification of the values associated to variab...
Definition: transformer.c:1907
transformer transformer_apply(transformer tf, transformer pre)
transformer transformer_apply(transformer tf, transformer pre): apply transformer tf on precondition ...
Definition: transformer.c:1559

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:

◆ no_elim()

Psysteme no_elim ( Psysteme  ps)
Parameters
pss

Definition at line 1306 of file transformer.c.

1307 {
1308  return ps;
1309 }

◆ 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 }
size_t gen_length(const list l)
Definition: list.c:150
#define TRANSFORMER(x)
TRANSFORMER.
Definition: ri.h:2841
transformer transformer_combine(volatile transformer t1, transformer t2)
transformer transformer_combine(transformer t1, transformer t2): compute the composition of transform...
Definition: transformer.c:238

References 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:

◆ parametric_transformer_empty_p()

static bool parametric_transformer_empty_p ( transformer  t,
Psysteme(*)(Psysteme, char *(*)(Variable))  normalize 
)
static

If true is returned, the transformer certainly is empty.

If false is returned, the transformer still might be empty, it all depends on the normalization procedure power. Beware of its execution time!

FI: the arguments seem to have no impact on the emptiness (i.e. falseness) of t

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

empty_p = !sc_faisabilite(ps);

empty_p = !sc_rational_feasibility_ofl_ctrl(ps, OFL_CTRL, true);

Normalize the transformer, use all "reasonnable" equations to reduce the problem size, check feasibility on the projected system

new_ps = normalize(new_ps, (char * (*)(Variable)) external_value_name);

FI: when dealing with interprocedural preconditions, the value mappings are initialized for the caller but the convex hull, which calls this function, must be performed in the calle value space.

Depending on the instance of "normalize", might always be trapped by the previous test.

Inconsistent equalities or inequalities between constants may be present. Project variable and temporary values and analyze resulting system. No equations should be left over unless equal constants are encoded differently. Inequations should be interpreted and checked.

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

No redundancy elimination...

new_ps = elim(new_ps);

sc_fprint(stderr, r, exernal_value_name);

Check remaining equalities and inequalities

sc_fprint(stderr, r, exernal_value_name);

Definition at line 2319 of file transformer.c.

2322 {
2323  /* FI: the arguments seem to have no impact on the emptiness
2324  * (i.e. falseness) of t
2325  */
2326  predicate pred = transformer_relation(t);
2327  Psysteme ps = predicate_system(pred);
2328  bool empty_p = false;
2329  volatile bool consistent_p = true;
2330  /* Automatic variables read in a CATCH block need to be declared volatile as
2331  * specified by the documentation*/
2332  Psysteme volatile new_ps = sc_dup (ps);
2333 
2334  pips_debug(9,"Begin for t=%p\n", t);
2335 
2336  /* empty_p = !sc_faisabilite(ps); */
2337  /* empty_p = !sc_rational_feasibility_ofl_ctrl(ps, OFL_CTRL, true); */
2338 
2339  /* Normalize the transformer, use all "reasonnable" equations
2340  * to reduce the problem
2341  * size, check feasibility on the projected system
2342  */
2343  /* new_ps = normalize(new_ps, (char * (*)(Variable)) external_value_name); */
2344  /* FI: when dealing with interprocedural preconditions, the value mappings
2345  * are initialized for the caller but the convex hull, which calls this function,
2346  * must be performed in the calle value space.
2347  */
2348  new_ps = normalize(new_ps, (char * (*)(Variable)) entity_local_name);
2349 
2350  if(SC_EMPTY_P(new_ps)) {
2351  empty_p = true;
2352  }
2353  else if(sc_empty_p(new_ps)) {
2354  /* Depending on the instance of "normalize", might always be trapped
2355  by the previous test. */
2356  empty_p = true;
2357  }
2358  else {
2359  if(string_analyzed_p() || float_analyzed_p()) {
2360  /* Inconsistent equalities or inequalities between constants may be
2361  present. Project variable and temporary values and analyze resulting system. No
2362  equations should be left over unless equal constants are encoded
2363  differently. Inequations should be interpreted and checked. */
2364  volatile Pvecteur b = VECTEUR_UNDEFINED;
2367  volatile Pbase b_min = sc_to_minimal_basis(new_ps);
2368 
2369  for (b = b_min ; !VECTEUR_UNDEFINED_P(b) && !empty_p; b = vecteur_succ(b)) {
2370  /* Automatic variables read in a CATCH block need to be declared volatile as
2371  * specified by the documentation*/
2372  Variable volatile var = vecteur_var(b);
2373  entity volatile e_var = (entity) var;
2374 
2375  if(!entity_constant_p(e_var)) {
2376 
2377  pips_debug(9, "Projection of %s\n", entity_name(e_var));
2378 
2380  {
2381  /* FC */
2382  pips_user_warning("overflow error in projection of %s, "
2383  "variable eliminated\n",
2384  entity_name(e_var));
2385  new_ps = sc_elim_var(new_ps, var);
2386  }
2387  TRY
2388  {
2389  /* sc_projection_along_variable_ofl_ctrl_timeout_ctrl */
2390  sc_projection_along_variable_ofl_ctrl
2391  (&new_ps, var, NO_OFL_CTRL);
2393  }
2394 
2395  sc_base_remove_variable(new_ps, var);
2396  /* No redundancy elimination... */
2397  /* new_ps = elim(new_ps); */
2398 
2399  ifdebug(10) {
2400  pips_debug(10, "System after projection of %s\n", entity_name(e_var));
2401  /* sc_fprint(stderr, r, exernal_value_name); */
2402  sc_fprint(stderr, new_ps, (char * (*)(Variable)) value_full_name);
2403  }
2404  empty_p = sc_empty_p(new_ps);
2405  }
2406  }
2407 
2408  base_rm(b_min);
2409 
2410  /* Check remaining equalities and inequalities */
2411 
2412  ifdebug(9) {
2413  pips_debug(9, "System after all projections or emptiness detection:\n");
2414  /* sc_fprint(stderr, r, exernal_value_name); */
2415  sc_fprint(stderr, new_ps, (char * (*)(Variable)) value_full_name);
2416  }
2417 
2418  if(!empty_p) {
2419  for(eq = sc_egalites(new_ps);
2420  !CONTRAINTE_UNDEFINED_P(eq) && consistent_p;
2421  eq = contrainte_succ(eq)) {
2422  consistent_p = constant_constraint_check(contrainte_vecteur(eq), true);
2423  }
2424 
2425  for(ineq = sc_inegalites(new_ps);
2426  !CONTRAINTE_UNDEFINED_P(ineq) && consistent_p;
2427  ineq = contrainte_succ(ineq)) {
2428  consistent_p = constant_constraint_check(contrainte_vecteur(ineq), false);
2429  }
2430  empty_p = !consistent_p;
2431  }
2432  }
2433  else {
2434  empty_p = false;
2435  }
2436 
2437  sc_rm(new_ps);
2438  }
2439 
2440  pips_debug(9,"End: %sfeasible\n", empty_p? "not " : "");
2441 
2442  return empty_p;
2443 }
#define CATCH(what)
@ overflow_error
#define UNCATCH(what)
#define TRY
#define CONTRAINTE_UNDEFINED_P(c)
#define contrainte_succ(c)
#define contrainte_vecteur(c)
passage au champ vecteur d'une contrainte "a la Newgen"
#define pips_user_warning
Definition: misc-local.h:146
void sc_base_remove_variable(Psysteme sc, Variable v)
Definition: sc.c:239
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
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
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
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
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
Psysteme sc_elim_var(Psysteme sc, Variable v)
package sur les systemes de contraintes sc
Definition: sc_unaires.c:49
static bool constant_constraint_check(Pvecteur v, bool is_equation_p)
Check if a transformer is empty.
Definition: transformer.c:2183
string value_full_name(entity)
for debugging purposes
Definition: value.c:1762
bool float_analyzed_p(void)
Definition: value.c:315
bool string_analyzed_p(void)
Definition: value.c:310
#define NO_OFL_CTRL
#define base_rm(b)

References base_rm, CATCH, constant_constraint_check(), contrainte_succ, CONTRAINTE_UNDEFINED, CONTRAINTE_UNDEFINED_P, contrainte_vecteur, entity_constant_p, entity_local_name(), entity_name, eq, float_analyzed_p(), ifdebug, NO_OFL_CTRL, overflow_error, pips_debug, pips_user_warning, predicate_system, sc_base_remove_variable(), sc_dup(), sc_elim_var(), sc_empty_p(), sc_fprint(), sc_rm(), sc_to_minimal_basis(), string_analyzed_p(), transformer_relation, TRY, UNCATCH, value_full_name(), vecteur_succ, VECTEUR_UNDEFINED, VECTEUR_UNDEFINED_P, and vecteur_var.

Referenced by transformer_empty_p(), and transformer_strongly_empty_p().

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

◆ 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)
#define basic_int_p(x)
Definition: ri.h:614
#define type_variable(x)
Definition: ri.h:2949
#define basic_pointer_p(x)
Definition: ri.h:635
#define entity_type(x)
Definition: ri.h:2792
#define variable_basic(x)
Definition: ri.h:3120
#define basic_logical_p(x)
Definition: ri.h:620
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:

◆ 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
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
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
struct Ssysteme * Psysteme
transformer transformer_projection(transformer t, list args)
values in args must be in t's base
Definition: transformer.c:1267
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
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
#define variable_dimensions(x)
Definition: ri.h:3122
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_identity()

static Psysteme sc_identity ( Psysteme  sc)
static

Predicate transformer package: sc complexity level.

include "boolean.h" include "vecteur.h" include "contrainte.h" include "sc.h" include "matrix.h"

Definition at line 52 of file transformer.c.

53 {
54  return sc;
55 }

Referenced by transformer_range(), and transformer_to_domain().

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

e and f are assumed to be values, Type independent.

transformer.c

Parameters
assignmentssignment

Definition at line 58 of file transformer.c.

59 {
61 
62  return tf;
63 }
transformer generic_equality_to_transformer(entity e, entity f, bool assignment, bool unary_minus_p)
Definition: transformer.c:72

References f(), and generic_equality_to_transformer().

Referenced by 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(), c_user_function_call_to_transformer(), constant_to_transformer(), generic_reference_to_transformer(), logical_reference_to_transformer(), pointer_expression_to_transformer(), pointer_unary_operation_to_transformer(), and string_expression_to_transformer().

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

◆ 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 }
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

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
return(s1)
Pvecteur vecteur
struct Scontrainte * succ
Pcontrainte inegalites
Definition: sc-local.h:71
Pcontrainte egalites
Definition: sc-local.h:70
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:

◆ 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 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
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 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 }
transformer transformer_dup(transformer t_in)
transformer package - basic routines
Definition: basic.c:49

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 }
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
bool transformer_empty_p(transformer t)
If true is returned, the transformer certainly is empty.
Definition: transformer.c:2455

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_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_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 }
void free_transformer(transformer p)
Definition: ri.c:2616
transformer copy_transformer(transformer p)
TRANSFORMER.
Definition: ri.c:2613
bool arguments_set_equal_p(list a1, list a2)
Set equality of lists a1 and a2.
Definition: arguments.c:181
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_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
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
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
char end
Definition: gtk_status.c:82
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
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_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
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...
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
transformer transformer_range(transformer tf)
Return the range of relation tf in a newly allocated transformer.
Definition: transformer.c:714
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 BASE_NULLE
MACROS SUR LES BASES.

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_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_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_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_general_intersection()

static transformer transformer_general_intersection ( transformer  t1,
transformer  t2,
bool  image_only 
)
static

Allocate a new transformer with constraints in t1 and t2.

If t2 has no arguments, it restrains the domain of t1. This is necessary if image_only is true.

If not, the two transformers are supposed to be two separate abstraction of the same transformation and an intersection of the relation graphs is performed.

no need to duplicate s2, it is done in sc_append. Psysteme s2 = sc_dup((Psysteme) predicate_system(transformer_relation(t2)));

Do not restrict the transition but the image of the relation t1 with constraints in t2.

intersect transition t1 and transition t2

Definition at line 539 of file transformer.c.

542 {
544 
545  pips_debug(9, "Begins with t1 = %p and t2 = %p, image_only=%s\n",
546  t1, t2, bool_to_string(image_only));
547 
548 
550  t = transformer_empty();
551  }
552  else {
554  /* no need to duplicate s2, it is done in sc_append.
555  Psysteme s2 = sc_dup((Psysteme) predicate_system(transformer_relation(t2))); */
557 
558  t = transformer_identity();
559  /*
560  pips_debug(9, "begin with s1 and s2:\n");
561  sc_dump(s1);
562  sc_dump(s2);
563  */
564 
565  s1 = sc_append(s1, s2);
566 
567  /*
568  pips_debug(9, "new s1:\n");
569  sc_dump(s1);
570  */
571 
573 
574  if(image_only) {
575  /* Do not restrict the transition but the image of the relation t1
576  with constraints in t2. */
577  if(!ENDP(transformer_arguments(t2))) {
578  dump_transformer(t2);
579  pips_assert("Transformer t2 has no arguments", ENDP(transformer_arguments(t2)));
580  }
582  }
583  else {
584  /* intersect transition t1 and transition t2 */
587  }
588  }
589 
590  pips_debug(9, "Exit with t=%p, for t1 = %p and t2 = %p\n", t, t1, t2);
591 
592  return t;
593 }
cons * dup_arguments(cons *args)
Definition: arguments.c:225
list arguments_intersection(list a1, list a2)
Build a new list with all entities occuring in both a1 and a2.
Definition: arguments.c:158
transformer transformer_empty()
Allocate an empty transformer.
Definition: basic.c:120
string bool_to_string(bool)
Definition: string.c:243

References arguments_intersection(), bool_to_string(), dump_transformer, dup_arguments(), ENDP, pips_assert, pips_debug, predicate_system, s1, sc_append(), sc_dup(), transformer_arguments, transformer_empty(), transformer_empty_p(), transformer_identity(), transformer_relation, and transformer_undefined.

Referenced by transformer_image_intersection(), transformer_intersection(), and transformer_safe_general_intersection().

+ Here is the call graph for this function:
+ 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_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_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 }
bool transformer_consistent_p(transformer p)
Definition: ri.c:2622
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
const char * external_value_name(entity)
Definition: value.c:753
Pbase base_dup(Pbase b)
Pbase base_dup(Pbase b) Note: this function changes the value of the pointer.
Definition: alloc.c:268
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_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  t,
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
#define entity_undefined
Definition: ri.h:2761
entity global_new_value_to_global_old_value(entity)
Definition: value.c:716
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(), 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_p(x)
Definition: ri.h:2516
#define storage_return(x)
Definition: ri.h:2518
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
#define BASE_NULLE_P(b)

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_general_intersection()

static transformer transformer_safe_general_intersection ( transformer  t1,
transformer  t2,
bool  image_only 
)
static

Allocate a new transformer.

Definition at line 622 of file transformer.c.

625 {
627 
629  tf = copy_transformer(t2);
630  else if(transformer_undefined_p(t2))
631  tf = copy_transformer(t1);
632  else
633  tf = transformer_general_intersection(t1, t2, image_only);
634 
635  return tf;
636 }

References copy_transformer(), transformer_general_intersection(), transformer_undefined, and transformer_undefined_p.

Referenced by transformer_safe_image_intersection(), and transformer_safe_intersection().

+ 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 }
transformer transformer_normalize(transformer t, int level)
Eliminate (some) rational or integer redundancy.
Definition: transformer.c:932

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
void free(void *)
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

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  tf,
entity m   __attribute__(unused) 
)

Provide a list of variables that might be forward translated into a stub when preconditions are propagated in callees.

Basically, remove nothing from the transformer base ?

Definition at line 2720 of file transformer.c.

2721 {
2722  list l = NIL;
2724  Pvecteur b = sc_base(sc), cb;
2725  for(cb=b; !VECTEUR_UNDEFINED_P(cb); cb = vecteur_succ(cb)) {
2726  Variable v = vecteur_var(cb);
2728  entity e = value_to_variable((entity) v);
2729  value ev = entity_initial(e);
2730  entity te = e;
2731  if(value_reference_p(ev)) {
2732  reference r = value_reference(ev);
2733  te = reference_variable(r);
2734  }
2735  if(!gen_in_list_p(te, l))
2736  l = CONS(ENTITY, te, l);
2737  }
2738  }
2739  return l;
2740 }

References CONS, ENTITY, entity_initial, gen_in_list_p(), local_temporary_value_entity_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 substitute_stubs_in_transformer().

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

◆ 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 }
#define entity_undefined_p(x)
Definition: ri.h:2762
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_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_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:

◆ varval_value_name_is_inferior_p()

static int varval_value_name_is_inferior_p ( Pvecteur pvarval1,
Pvecteur pvarval2 
)
static

Definition at line 870 of file transformer.c.

871 {
872  int is_inferior = true;
873  const char* s1 = generic_value_name((entity) vecteur_var(*pvarval1));
874  const char* s2 = generic_value_name((entity) vecteur_var(*pvarval2));
875 
876  is_inferior = (strcmp(s1, s2) > 0 );
877 
878  return is_inferior;
879 }
const char * generic_value_name(entity e)
Definition: prettyprint.c:81

References generic_value_name(), s1, and vecteur_var.

Referenced by transformer_normalize().

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