PIPS
expression.c File Reference
#include <stdio.h>
#include <string.h>
#include "genC.h"
#include "linear.h"
#include "misc.h"
#include "properties.h"
#include "ri.h"
#include "effects.h"
#include "ri-util.h"
#include "prettyprint.h"
#include "effects-util.h"
#include "text-util.h"
#include "effects-simple.h"
#include "pips-libs.h"
#include "transformer.h"
#include "semantics.h"
+ Include dependency graph for expression.c:

Go to the source code of this file.

Data Structures

struct  interval_product
 

Macros

#define DEBUG_TRANSFORMER_ADD_CONDITION_INFORMATION_UPDOWN   7
 HANDLING OF CONDITIONS. More...
 
#define DEBUG_TRANSFORMER_ADD_RELATION_INFORMATION   7
 

Functions

static points_to_graph get_points_to_graph_from_statement (_UNUSED_ statement st)
 semantic analysis: processing of expressions, with or without preconditions. More...
 
static list expression_to_points_to_sinks (_UNUSED_ expression e, _UNUSED_ points_to_graph in)
 
static list expression_to_points_to_sources (_UNUSED_ expression e, _UNUSED_ points_to_graph in)
 
transformer generic_reference_to_transformer (entity v, reference r, transformer pre, bool is_internal)
 TYPE INDEPENDENT OPERATIONS. More...
 
static transformer generic_minmax_to_transformer (entity e, list args, transformer pre, bool minmax, bool is_internal)
 
static transformer unary_minus_operation_to_transformer (entity v, expression e1, transformer pre, bool is_internal)
 Type independent. More...
 
transformer any_basic_update_operation_to_transformer (entity tmp, entity v, entity op)
 See also any_basic_update_to_transformer(), which should be based on this function. More...
 
static transformer generic_abs_to_transformer (entity, expression, transformer, bool)
 forward declaration More...
 
static transformer generic_unary_operation_to_transformer (entity e, entity op, expression e1, transformer pre, bool is_internal)
 
static transformer addition_operation_to_transformer (entity v, expression e1, expression e2, transformer pre, bool addition_p, bool is_internal)
 Type independent. More...
 
transformer any_assign_operation_to_transformer (entity tmp, list args, transformer pre, bool is_internal __attribute__((unused)))
 Similar to any_assign_to_transformer(), which is a simpler case. More...
 
transformer safe_any_assign_operation_to_transformer (entity tmp, list args, transformer pre, bool is_internal)
 
static transformer update_operation_to_transformer (entity v, entity op, expression e1, expression e2, transformer pre, bool is_internal)
 v = (e1 = e1 op e2) ; e1 must be a reference; does not compute information for dereferenced pointers such as in "*p += 2;" More...
 
static transformer constant_to_transformer (entity v, expression rhs)
 
static transformer transformer_add_condition_information_updown (transformer, expression, transformer, bool, bool)
 call transformer_add_condition_information_updown() recursively on both sub-expressions if veracity == true; else try your best... More...
 
static transformer transformer_add_anded_conditions_updown (transformer pre, expression c1, expression c2, transformer context, bool veracity, bool upwards)
 
static transformer transformer_add_ored_conditions_updown (transformer pre, expression c1, expression c2, transformer context, bool veracity, bool upwards)
 call transformer_add_condition_information_updown() recursively on both sub-expressions if veracity == false; else try to do your best... More...
 
static transformer transformer_add_call_condition_information_updown (transformer pre, entity op, list args, transformer context, bool veracity, bool upwards)
 
transformer transformer_add_condition_information (transformer pre, expression c, transformer context, bool veracity)
 
transformer precondition_add_condition_information (transformer pre, expression c, transformer context, bool veracity)
 context might be derivable from pre as transformer_range(pre) but this is sometimes very computationally intensive, e.g. More...
 
transformer transformer_add_domain_condition (transformer tf, expression c, transformer context, bool veracity)
 
transformer transformer_add_range_condition (transformer tf, expression c, transformer context, bool veracity)
 
transformer simple_affine_to_transformer (entity e, Pvecteur a, bool is_internal)
 INTEGER EXPRESSIONS. More...
 
transformer affine_to_transformer (entity e, Pvecteur a, bool assignment)
 
transformer affine_increment_to_transformer (entity e, Pvecteur a)
 
static transformer modulo_of_a_constant_to_transformer (entity e, int lb1, int lb2, int ub2)
 
static transformer modulo_of_a_negative_value_to_transformer (entity e, int lb1, int ub1, int lb2, int ub2)
 e = [lb1,ub1] % [lb2,ub2] with ub1<=0 More...
 
static transformer modulo_of_a_positive_value_to_transformer (entity e, int lb1, int ub1, int lb2, int ub2)
 
transformer modulo_by_a_constant_to_transformer (entity v1, transformer prec, entity v2, int k)
 Analyze v2 % k, with v2 constrainted by tf, assuming tf is a precondition. More...
 
static transformer modulo_to_transformer (entity e, expression arg1, expression arg2, transformer pre, bool is_internal __attribute__((unused)))
 Modulo and integer division. More...
 
static transformer iabs_to_transformer (entity v, expression expr, transformer pre, bool is_internal)
 
static transformer integer_divide_to_transformer (entity e, expression arg1, expression arg2, transformer pre, bool is_internal)
 More could be done along the line of integer_multiply_to_transformer()... More...
 
static transformer integer_right_shift_to_transformer (entity e, expression arg1, expression arg2, transformer pre, bool is_internal)
 More could be done along the line of integer_left_shift_to_transformer()... More...
 
static transformer integer_multiply_to_transformer (entity v, expression e1, expression e2, transformer prec, bool is_internal)
 Assumes that e1 and e2 are integer expressions, i.e. More...
 
static transformer expression_multiply_sizeof_to_transformer (entity v, expression e1, transformer prec, bool is_internal)
 cut-and-pasted and adapted from multiply_to_transformer();
More...
 
static transformer integer_left_shift_to_transformer (entity v, expression e1, expression e2, transformer prec, bool is_internal)
 Assumes that e1 and e2 are integer expressions, i.e. More...
 
static transformer integer_power_to_transformer (entity e, expression arg1, expression arg2, transformer prec, bool is_internal)
 
static transformer integer_minmax_to_transformer (entity v, list args, transformer pre, bool is_min, bool is_internal)
 
static transformer min0_to_transformer (entity e, list args, transformer pre, bool is_internal)
 
static transformer max0_to_transformer (entity e, list args, transformer pre, bool is_internal)
 
transformer assign_operation_to_transformer (entity val, expression lhs, expression rhs, transformer pre)
 Returns an undefined transformer in case of failure. More...
 
transformer points_to_unary_operation_to_transformer (entity e, entity op, expression e1, transformer pre, bool is_internal, bool is_pointer)
 This function is redundant with generic_unary_operation_to_transformer() except for its use of parameter is_pointer. More...
 
static transformer integer_nullary_operation_to_transformer (entity e __attribute__((unused)), entity f __attribute__((unused)), transformer pre __attribute__((unused)), bool is_internal __attribute__((unused)))
 FI: this function is no longer useful (11 August 2013) More...
 
static transformer integer_unary_operation_to_transformer (entity e, entity op, expression e1, transformer pre, bool is_internal)
 
static transformer process_bounds_for_divide (transformer tf, entity v, entity v1, int lb1, int ub1, entity v2, int lb2, int ub2)
 Auxiliary function for non-affine operators such as divide, multiply, modulo... More...
 
static transformer integer_binary_operation_to_transformer (entity e, entity op, expression e1, expression e2, transformer pre, bool is_internal)
 
static transformer integer_call_expression_to_transformer (entity e, expression expr, transformer pre, bool is_internal)
 
transformer expression_effects_to_transformer (expression expr)
 
transformer integer_expression_to_transformer (entity v, expression expr, transformer pre, bool is_internal)
 Do check wrt to value mappings... More...
 
transformer safe_integer_expression_to_transformer (entity v, expression expr, transformer pre, bool is_internal)
 Always return a defined transformer, using effects in case a more precise analysis fails. More...
 
transformer transformer_logical_inequalities_add (transformer tf, entity v)
 PROCESSING OF LOGICAL EXPRESSIONS. More...
 
static transformer logical_constant_to_transformer (entity v, entity f)
 
static transformer logical_unary_operation_to_transformer (entity v, call c, transformer pre, bool is_internal)
 
static transformer logical_binary_operation_to_transformer (entity v, call c, transformer pre, bool is_internal)
 
static transformer logical_binary_function_to_transformer (entity v, call c, transformer pre, bool is_internal)
 
static transformer logical_reference_to_transformer (entity v, entity r, bool is_internal)
 v is assumed to be a temporary value and r a logical program variable More...
 
transformer logical_intrinsic_to_transformer (entity v, call c, transformer pre, bool is_internal)
 
transformer logical_expression_to_transformer (entity v, expression rhs, transformer pre, bool is_internal)
 Could be used to compute preconditions too. More...
 
transformer string_expression_to_transformer (entity v, expression rhs)
 
static transformer float_unary_operation_to_transformer (entity e, entity op, expression e1, transformer pre, bool is_internal)
 
static transformer float_binary_operation_to_transformer (entity e, entity op, expression e1, expression e2, transformer pre, bool is_internal)
 
static transformer float_call_expression_to_transformer (entity v, expression expr, transformer pre, bool is_internal)
 
transformer float_expression_to_transformer (entity v, expression rhs, transformer pre, bool is_internal)
 
static bool have_null_value_in_pointer_expression_p (expression expr)
 POINTER EXPRESSION. More...
 
static bool have_sizeof_value_in_multiply_pointer_expression_p (expression expr)
 Maybe move in ri-util/expression.c or in effect-util/pointer_values.c. More...
 
static transformer pointer_unary_operation_to_transformer (entity e, entity op, expression e1, transformer pre, bool is_internal)
 
static transformer pointer_binary_operation_to_transformer (entity e, expression expr, transformer pre, bool is_internal)
 
static transformer pointer_call_expression_to_transformer (entity e, expression expr, transformer pre, bool is_internal)
 
transformer pointer_expression_to_transformer (entity v, expression expr, transformer pre, bool is_internal)
 
static int semantics_basic_tag (basic b)
 Assimilate enum and logical to int (used when they appear in logical operations) More...
 
transformer transformer_add_any_relation_information (transformer pre, entity op, expression e1, expression e2, transformer context, bool veracity, bool upwards)
 compute transformer or precondition More...
 
transformer any_expression_side_effects_to_transformer (expression e, transformer p, bool is_internal __attribute__((unused)))
 The value of the expression is irrelevant, but its sub-expressions may generate a transformer. More...
 
transformer any_expressions_side_effects_to_transformer (list el, transformer p, bool is_internal)
 same as any_expression_side_effects_to_transformer() but for a list of expressions More...
 
transformer safe_any_expression_side_effects_to_transformer (expression e, transformer p, bool is_internal)
 Same as any_expression_side_effects_to_transformer() but effects are used to always generate a transformer. More...
 
transformer any_expression_to_transformer (entity v, expression expr, transformer pre, bool is_internal)
 A set of functions to compute the transformer associated to an expression evaluated in a given context. More...
 
transformer safe_any_expression_to_transformer (entity v, expression expr, transformer pre, bool is_internal)
 Always return a usable transformer. More...
 
transformer expression_to_transformer (expression exp, transformer pre, list el)
 Just to capture side effects as the returned value is ignored. More...
 
transformer safe_expression_to_transformer (expression exp, transformer pre)
 
transformer condition_to_transformer (expression cond, transformer pre, bool veracity)
 To capture side effects and to add C twist for numerical conditions. More...
 
transformer conditional_to_transformer (expression cond, expression te, expression fe, transformer pre, list ef)
 FI: not too smart to start with the special case with no value returned, just side-effects... More...
 
transformer any_conditional_to_transformer (entity v, list args, transformer pre)
 Take care of the returned value. More...
 
transformer logical_not_to_transformer (entity v, list args, transformer pre)
 returns the transformer associated to a C logical not, !, applied to an integer argument, when meaningful, and transformer_undefined otherwise. More...
 
transformer bitwise_xor_to_transformer (entity v, list args, transformer pre)
 returns the transformer associated to a C bitwise xor, ^, applied to two integer argument, when meaningful, and transformer_undefined otherwise. More...
 
transformer expressions_to_transformer (list expl, transformer pre)
 Compute the transformer associated to a list of expressions such as "i=0, j = 1;". More...
 
transformer any_expressions_to_transformer (entity v, list expl, transformer pre)
 Compute the transformer associated to a list of expressions such as "i=0, j = 1;". More...
 
bool precondition_minmax_of_value (entity val, transformer tr, intptr_t *pmin, intptr_t *pmax)
 compute integer bounds pmax, pmin of value val under preconditions tr require value mappings set ! More...
 
bool precondition_minmax_of_expression (expression exp, transformer tr, intptr_t *pmin, intptr_t *pmax)
 compute integer bounds pmax, pmin of expression exp under preconditions tr require value mappings set ! More...
 
void simplify_minmax_expression (expression e, transformer tr)
 tries hard to simplify expression e if it is a min or a max operator, by evaluating it under preconditions tr. More...
 
bool false_condition_wrt_precondition_p (expression c, transformer pre)
 
bool true_condition_wrt_precondition_p (expression c, transformer pre)
 
bool eval_condition_wrt_precondition_p (expression c, transformer pre, bool veracity)
 
transformer transformer_add_integer_relation_information (transformer pre, entity relop, expression e1, expression e2, bool veracity, bool upwards)
 It is supposed to be obsolete but is still called. More...
 
int simplify_boolean_expression_with_precondition (expression e, transformer p)
 Simplification of bool expressions with precondition. More...
 
bool semantics_usable_points_to_reference_p (reference rlhs, expression lhs, int n)
 See if references rlhs is usable and process null, undefined and anywhere locations defined by rlhs. More...
 
transformer lhs_expression_to_transformer (entity e, expression lhs, transformer pre)
 This function deals with e1.e2 and e1->e2, not with simple references such as x or a[i]. More...
 

Macro Definition Documentation

◆ DEBUG_TRANSFORMER_ADD_CONDITION_INFORMATION_UPDOWN

#define DEBUG_TRANSFORMER_ADD_CONDITION_INFORMATION_UPDOWN   7

HANDLING OF CONDITIONS.

Definition at line 716 of file expression.c.

◆ DEBUG_TRANSFORMER_ADD_RELATION_INFORMATION

#define DEBUG_TRANSFORMER_ADD_RELATION_INFORMATION   7

Function Documentation

◆ addition_operation_to_transformer()

static transformer addition_operation_to_transformer ( entity  v,
expression  e1,
expression  e2,
transformer  pre,
bool  addition_p,
bool  is_internal 
)
static

Type independent.

Most of it should be factored out for binary operations. v = e1 + e2 or v = e1 - e2

sub-expressions are not necessarily integer? Then the expression should not be integer?

Too early: you are projecting v and loosing all useful information within an expression!

tf = transformer_temporary_value_projection(tf);

Definition at line 438 of file expression.c.

444 {
446 
447  // FI: the types of subexpressions e1 and e2 should be checked
448  // because they might be pointers or a combination of pointer and
449  // integer. Equations must be adapted by multiplying entities with
450  // sizeof() constants. Not clear how to do this with symbolic
451  // sizeofs used by Nelson to improve portability.
452 
455  /* sub-expressions are not necessarily integer? Then the expression
456  should not be integer? */
457  transformer tf1 = safe_any_expression_to_transformer(tmp1, e1, pre, is_internal);
459  : transformer_apply(tf1, pre);
460  transformer npre = transformer_range(post);
461  transformer tf2 = safe_any_expression_to_transformer(tmp2, e2, npre, is_internal);
463  transformer tf_op = simple_addition_to_transformer(v, tmp1, tmp2, addition_p);
464 
465  free_transformer(post);
466  free_transformer(npre);
467 
468  pips_debug(9, "Begin officialy... but a lot has been done already!\n");
469 
471  tf = transformer_safe_image_intersection(tf12, tf_op);
472 
473  /*
474  ifdebug(9) {
475  pips_debug(9, "before projection, with temporaries v=%s, tmp1=%s, tmp2=%s,"
476  " transformer rf=%p\n",
477  entity_local_name(v), entity_local_name(tmp1),
478  entity_local_name(tmp2), tf);
479  dump_transformer(tf);
480  }
481  */
482 
483  /* Too early: you are projecting v and loosing all useful information
484  within an expression! */
485  /* tf = transformer_temporary_value_projection(tf); */
486 
487  free_transformer(tf2);
488  free_transformer(tf12);
489  free_transformer(tf_op);
490 
491  pips_debug(9, "End with transformer tf=%p\n", tf);
492  ifdebug(9) dump_transformer(tf);
493 
494  return tf;
495 }
void free_transformer(transformer p)
Definition: ri.c:2616
transformer transformer_identity()
Allocate an identity transformer.
Definition: basic.c:110
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define dump_transformer(t)
Definition: print.c:355
#define transformer_undefined
Definition: ri.h:2847
#define transformer_undefined_p(x)
Definition: ri.h:2848
#define entity_type(x)
Definition: ri.h:2792
transformer safe_any_expression_to_transformer(entity v, expression expr, transformer pre, bool is_internal)
Always return a usable transformer.
Definition: expression.c:5156
return(s1)
#define ifdebug(n)
Definition: sg.c:47
transformer simple_addition_to_transformer(entity e, entity e1, entity e2, bool addition_p)
e and e1 and e2 are assumed to be values.
Definition: transformer.c:106
transformer transformer_safe_image_intersection(transformer t1, transformer t2)
Allocate a new transformer.
Definition: transformer.c:647
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 s...
Definition: transformer.c:493
transformer transformer_apply(transformer tf, transformer pre)
transformer transformer_apply(transformer tf, transformer pre): apply transformer tf on precondition ...
Definition: transformer.c:1559
transformer transformer_range(transformer tf)
Return the range of relation tf in a newly allocated transformer.
Definition: transformer.c:714
entity make_local_temporary_value_entity(type)
Definition: value.c:605

References dump_transformer, entity_type, free_transformer(), ifdebug, make_local_temporary_value_entity(), pips_debug, safe_any_expression_to_transformer(), simple_addition_to_transformer(), transformer_apply(), transformer_identity(), transformer_range(), transformer_safe_combine_with_warnings(), transformer_safe_image_intersection(), transformer_undefined, and transformer_undefined_p.

Referenced by float_binary_operation_to_transformer(), integer_binary_operation_to_transformer(), and pointer_binary_operation_to_transformer().

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

◆ affine_increment_to_transformer()

transformer affine_increment_to_transformer ( entity  e,
Pvecteur  a 
)

Definition at line 1269 of file expression.c.

1270 {
1272 
1273  tf = affine_to_transformer(e, a, false);
1274 
1275  return tf;
1276 }
transformer affine_to_transformer(entity e, Pvecteur a, bool assignment)
Definition: expression.c:1212

References affine_to_transformer(), and transformer_undefined.

Referenced by add_loop_index_exit_value().

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

◆ affine_to_transformer()

transformer affine_to_transformer ( entity  e,
Pvecteur  a,
bool  assignment 
)

must be duplicated right now because it will be renamed and checked at the same time by value_mappings_compatible_vector_p()

Parameters
assignmentssignment

Definition at line 1212 of file expression.c.

1213 {
1215  Pvecteur ve = vect_new((Variable) e, VALUE_ONE);
1216  entity e_new = entity_to_new_value(e);
1217  entity e_old = entity_to_old_value(e);
1218  cons * tf_args = CONS(ENTITY, e_new, NIL);
1219  /* must be duplicated right now because it will be
1220  renamed and checked at the same time by
1221  value_mappings_compatible_vector_p() */
1222  Pvecteur vexpr = vect_dup(a);
1223  Pcontrainte c;
1225 
1226  pips_debug(8, "begin\n");
1227 
1228  ifdebug(9) {
1229  pips_debug(9, "\nLinearized expression:\n");
1230  vect_dump(vexpr);
1231  }
1232 
1233  if(!assignment) {
1234  vect_add_elem(&vexpr, (Variable) e, (Value) 1);
1235 
1236  ifdebug(8) {
1237  pips_debug(8, "\nLinearized expression for incrementation:\n");
1238  vect_dump(vexpr);
1239  }
1240  }
1241 
1244  ve = vect_variable_rename(ve,
1245  (Variable) e,
1246  (Variable) e_new);
1247  (void) vect_variable_rename(vexpr,
1248  (Variable) e_new,
1249  (Variable) e_old);
1250  eq = vect_substract(ve, vexpr);
1251  vect_rm(ve);
1252  vect_rm(vexpr);
1253  c = contrainte_make(eq);
1254  tf = make_transformer(tf_args,
1256  }
1257  else {
1258  vect_rm(eq);
1259  vect_rm(ve);
1260  vect_rm(vexpr);
1261  tf = transformer_undefined;
1262  }
1263 
1264  pips_debug(8, "end\n");
1265 
1266  return tf;
1267 }
transformer make_transformer(list a1, predicate a2)
Definition: ri.c:2649
predicate make_predicate(Psysteme a1)
Definition: ri.c:1820
int Value
#define VALUE_ONE
Pvecteur vect_variable_rename(Pvecteur v, Variable v_old, Variable v_new)
Pvecteur vect_variable_rename(Pvecteur v, Variable v_old, Variable v_new): rename the potential coord...
Definition: base.c:366
#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 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
void vect_dump(Pvecteur v)
void vect_dump(Pvecteur v): print sparse vector v on stderr.
Definition: io.c:304
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
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
bool value_mappings_compatible_vector_p(Pvecteur iv)
transform a vector based on variable entities into a vector based on new value entities when possible...
Definition: mappings.c:924
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
entity entity_to_old_value(entity)
Definition: value.c:869
#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
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
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_substract(Pvecteur v1, Pvecteur v2)
Pvecteur vect_substract(Pvecteur v1, Pvecteur v2): allocation d'un vecteur v dont la valeur est la di...
Definition: binaires.c:75
void vect_add_elem(Pvecteur *pvect, Variable var, Value val)
void vect_add_elem(Pvecteur * pvect, Variable var, Value val): addition d'un vecteur colineaire au ve...
Definition: unaires.c:72

References CONS, contrainte_make(), CONTRAINTE_UNDEFINED, ENTITY, entity_to_new_value(), entity_to_old_value(), eq, ifdebug, make_predicate(), make_transformer(), NIL, pips_debug, sc_make(), transformer_undefined, value_mappings_compatible_vector_p(), VALUE_ONE, vect_add_elem(), vect_dump(), vect_dup(), vect_new(), vect_rm(), vect_substract(), vect_variable_rename(), and VECTEUR_NUL.

Referenced by affine_increment_to_transformer().

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

◆ any_assign_operation_to_transformer()

transformer any_assign_operation_to_transformer ( entity  tmp,
list  args,
transformer  pre,
bool is_internal   __attribute__(unused) 
)

Similar to any_assign_to_transformer(), which is a simpler case.

Here, we cope with expression such as the lhs of j = (i=1);

The lhs must be a scalar reference to perform an interesting analysis

Is it standard compliant? The assigned variable is modified by the rhs.

Take care of aliasing

tf = transformer_value_substitute(tf, v_new, v_old);

Parameters
prearguments for assign
__attribute__precondition

Definition at line 499 of file expression.c.

503 {
505  //transformer tfe = transformer_undefined;
506  expression lhs = EXPRESSION(CAR(args));
507  expression rhs = EXPRESSION(CAR(CDR(args)));
508  syntax slhs = expression_syntax(lhs);
509 
510  pips_assert("2 args to assign", CDR(CDR(args))==NIL);
511 
512  /* The lhs must be a scalar reference to perform an interesting analysis */
513  if(syntax_reference_p(slhs)) {
514  reference rlhs = syntax_reference(slhs);
515  if(ENDP(reference_indices(rlhs))) {
516  entity v = reference_variable(rlhs);
517 
518  if(entity_has_values_p(v)) {
519  entity v_new = entity_to_new_value(v);
520  entity v_old = entity_to_old_value(v);
522 
523  tf = any_expression_to_transformer(tmp2, rhs, pre, true);
524 
525  if(!transformer_undefined_p(tf)) {
526 
527  pips_debug(9, "A transformer has been obtained:\n");
528  ifdebug(9) dump_transformer(tf);
529 
531  /* Is it standard compliant? The assigned variable is
532  modified by the rhs. */
533  transformer teq = simple_equality_to_transformer(v, tmp, true);
534  string s = expression_to_string(rhs);
535 
536  semantics_user_warning("Variable \"%s\" in lhs is uselessly or illegally updated by rhs '%s'\n",
537  entity_user_name(v), s);
538  //entity_local_name(v), s);
539 
540  free(s);
541 
542  tf = transformer_combine(tf, teq);
543  free_transformer(teq);
544  }
545  else {
546  /* Take care of aliasing */
547  entity v_repr = value_to_variable(v_new);
548 
549  /* tf = transformer_value_substitute(tf, v_new, v_old); */
550  tf = transformer_value_substitute(tf, v_new, v_old);
551 
552  pips_debug(9,"After substitution v_new=%s -> v_old=%s\n",
553  entity_local_name(v_new), entity_local_name(v_old));
554 
555  tf = transformer_value_substitute(tf, tmp2, v_new);
556 
557  pips_debug(9,"After substitution tmp=%s -> v_new=%s\n",
558  entity_local_name(tmp2), entity_local_name(v_new));
559 
561  }
562  //tf = generic_equality_to_transformer(tmp, tmp2, false, false);
563  //tf = transformer_combine(tf, tfe);
564  }
565  }
566  }
567  }
568 
569  pips_debug(6,"return tf=%p\n", tf);
570  ifdebug(6) (void) print_transformer(tf);
571  pips_debug(8,"end\n");
572  return tf;
573 }
bool entity_is_argument_p(entity e, cons *args)
Definition: arguments.c:150
transformer transformer_add_modified_variable(transformer tf, entity var)
FI: this function does not end up with a consistent transformer because the old value is not added to...
Definition: basic.c:889
if(!(yy_init))
Definition: genread_lex.c:1029
void free(void *)
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
string expression_to_string(expression e)
Definition: expression.c:77
#define print_transformer(t)
Definition: print.c:357
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
#define syntax_reference_p(x)
Definition: ri.h:2728
#define syntax_reference(x)
Definition: ri.h:2730
#define reference_variable(x)
Definition: ri.h:2326
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define transformer_arguments(x)
Definition: ri.h:2871
#define reference_indices(x)
Definition: ri.h:2328
#define expression_syntax(x)
Definition: ri.h:1247
#define semantics_user_warning
transformer any_expression_to_transformer(entity v, expression expr, transformer pre, bool is_internal)
A set of functions to compute the transformer associated to an expression evaluated in a given contex...
Definition: expression.c:4993
transformer transformer_combine(volatile transformer t1, transformer t2)
transformer transformer_combine(transformer t1, transformer t2): compute the composition of transform...
Definition: transformer.c:238
transformer transformer_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
transformer simple_equality_to_transformer(entity e, entity f, bool assignment)
e and f are assumed to be values, Type independent.
Definition: transformer.c:58
bool entity_has_values_p(entity)
This function could be made more robust by checking the storage of e.
Definition: value.c:911
entity value_to_variable(entity)
Get the primitive variable associated to any value involved in a transformer.
Definition: value.c:1624

References any_expression_to_transformer(), CAR, CDR, dump_transformer, ENDP, entity_has_values_p(), entity_is_argument_p(), entity_local_name(), entity_to_new_value(), entity_to_old_value(), entity_type, entity_user_name(), EXPRESSION, expression_syntax, expression_to_string(), free(), free_transformer(), ifdebug, make_local_temporary_value_entity(), NIL, pips_assert, pips_debug, print_transformer, reference_indices, reference_variable, semantics_user_warning, simple_equality_to_transformer(), syntax_reference, syntax_reference_p, transformer_add_modified_variable(), transformer_arguments, transformer_combine(), transformer_undefined, transformer_undefined_p, transformer_value_substitute(), and value_to_variable().

Referenced by any_basic_update_operation_to_transformer(), safe_any_assign_operation_to_transformer(), and update_operation_to_transformer().

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

◆ any_basic_update_operation_to_transformer()

transformer any_basic_update_operation_to_transformer ( entity  tmp,
entity  v,
entity  op 
)

See also any_basic_update_to_transformer(), which should be based on this function.

FI: why

Parameters
tmpmp
opp

Definition at line 317 of file expression.c.

318 {
324  list args = list_undefined;
325 
327  inc = int_to_expression(1);
328  else
329  inc = int_to_expression(-1);
330 
331  n_rhs = MakeBinaryCall(plus, inc, entity_to_expression(v));
332 
333  /* FI: why*/
334  args = CONS(EXPRESSION, ve, CONS(EXPRESSION, n_rhs, NIL));
336  args,
338  false);
341  else
342  tf = transformer_add_equality(tf, v, tmp);
343  gen_full_free_list(args);
344 
345  pips_debug(6,"return tf=%p\n", tf);
346  ifdebug(6) (void) dump_transformer(tf);
347  pips_debug(8,"end\n");
348  return tf;
349 }
transformer transformer_add_equality(transformer tf, entity v1, entity v2)
Add an equality between two values (two variables?)
Definition: basic.c:436
void gen_full_free_list(list l)
Definition: genClib.c:1023
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
#define ENTITY_POST_DECREMENT_P(e)
#define ENTITY_POST_INCREMENT_P(e)
#define ENTITY_PRE_INCREMENT_P(e)
#define PLUS_C_OPERATOR_NAME
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188
#define expression_undefined
Definition: ri.h:1223
transformer any_assign_operation_to_transformer(entity tmp, list args, transformer pre, bool is_internal __attribute__((unused)))
Similar to any_assign_to_transformer(), which is a simpler case.
Definition: expression.c:499

References any_assign_operation_to_transformer(), CONS, dump_transformer, entity_intrinsic(), ENTITY_POST_DECREMENT_P, ENTITY_POST_INCREMENT_P, ENTITY_PRE_INCREMENT_P, entity_to_expression(), entity_to_old_value(), EXPRESSION, expression_undefined, gen_full_free_list(), ifdebug, int_to_expression(), list_undefined, MakeBinaryCall(), NIL, pips_debug, PLUS_C_OPERATOR_NAME, transformer_add_equality(), and transformer_undefined.

Referenced by generic_unary_operation_to_transformer(), and pointer_unary_operation_to_transformer().

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

◆ any_conditional_to_transformer()

transformer any_conditional_to_transformer ( entity  v,
list  args,
transformer  pre 
)

Take care of the returned value.

About a cut-and-paste of previous function, conditional_to_transformer().

Parameters
argsrgs
prere

Definition at line 5524 of file expression.c.

5527 {
5528  expression cond = EXPRESSION(CAR(args));
5529  expression te = EXPRESSION(CAR(CDR(args)));
5530  expression fe = EXPRESSION(CAR(CDR(CDR(args))));
5532  transformer ttf = condition_to_transformer(cond, pre, true);
5533  transformer t_pre = transformer_apply(ttf, pre);
5534  transformer t_pre_r = transformer_range(t_pre);
5535  transformer tet = safe_any_expression_to_transformer(v, te, t_pre_r, true);
5536  transformer ftf = condition_to_transformer(cond, pre, false);
5537  transformer f_pre = transformer_apply(ftf, pre);
5538  transformer f_pre_r = transformer_range(f_pre);
5539  transformer fet = safe_any_expression_to_transformer(v, fe, f_pre_r, true);
5540 
5541  ttf = transformer_combine(ttf, tet);
5542  ftf = transformer_combine(ftf, fet);
5543  tf = transformer_convex_hull(ttf, ftf);
5544 
5545  free_transformer(ttf);
5546  free_transformer(ftf);
5547  free_transformer(tet);
5548  free_transformer(fet);
5549  free_transformer(t_pre_r);
5550  free_transformer(f_pre_r);
5551  free_transformer(t_pre);
5552  free_transformer(f_pre);
5553 
5554  //if(transformer_undefined_p(tf))
5555  // tf = effects_to_transformer(ef);
5556  return tf;
5557 }
transformer condition_to_transformer(expression cond, transformer pre, bool veracity)
To capture side effects and to add C twist for numerical conditions.
Definition: expression.c:5348
transformer transformer_convex_hull(transformer t1, transformer t2)
transformer transformer_convex_hull(t1, t2): compute convex hull for t1 and t2; t1 and t2 are slightl...
Definition: convex_hull.c:216

References CAR, CDR, condition_to_transformer(), EXPRESSION, free_transformer(), safe_any_expression_to_transformer(), transformer_apply(), transformer_combine(), transformer_convex_hull(), transformer_range(), and transformer_undefined.

Referenced by integer_call_expression_to_transformer(), and pointer_call_expression_to_transformer().

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

◆ any_expression_side_effects_to_transformer()

transformer any_expression_side_effects_to_transformer ( expression  e,
transformer  p,
bool is_internal   __attribute__(unused) 
)

The value of the expression is irrelevant, but its sub-expressions may generate a transformer.

FI: use Newgen to reimplement this using abstract transformers to simplify the recursion ?

Definition at line 4845 of file expression.c.

4849 {
4851  syntax s = expression_syntax(e);
4852  switch(syntax_tag(s)) {
4853  case is_syntax_reference: {
4854  reference r = syntax_reference(s);
4855  list el = reference_indices(r);
4856  //tf = any_expressions_side_effects_to_transformer(el, p, is_internal);
4857  tf = expressions_to_transformer(el, p);
4858  };
4859  break;
4860  case is_syntax_range: {
4861  pips_internal_error("Not implemented yet.\n");
4862  break;
4863  };
4864  case is_syntax_call: {
4865  call c = syntax_call(s);
4866  list el = call_arguments(c);
4867  tf = any_expressions_side_effects_to_transformer(el, p, is_internal);
4868  break;
4869  };
4870  case is_syntax_cast: {
4871  cast c = syntax_cast(s);
4872  expression ce = cast_expression(c);
4873  tf = any_expression_side_effects_to_transformer(ce, p, is_internal);
4874  break;
4875  };
4880  tf = any_expression_side_effects_to_transformer(soee, p, is_internal);
4881  }
4882  break;
4883  };
4884  case is_syntax_subscript: {
4885  subscript ss = syntax_subscript(s);
4886  expression ae = subscript_array(ss);
4887  list sel = subscript_indices(ss);
4888  tf =
4889  any_expression_side_effects_to_transformer(ae, p, is_internal);
4890  transformer etf =
4891  any_expressions_side_effects_to_transformer(sel, p, is_internal);
4892  tf = transformer_combine(tf, etf);
4893  free_transformer(etf);
4894  break;
4895  };
4896  case is_syntax_application: {
4899  list al = application_arguments(a);
4900  tf = any_expression_side_effects_to_transformer(fe, p, is_internal);
4901  transformer etf =
4902  any_expressions_side_effects_to_transformer(al, p, is_internal);
4903  tf = transformer_combine(tf, etf);
4904  free_transformer(etf);
4905  break;
4906  };
4907  case is_syntax_va_arg: {
4908  // FI: what could be useful ? Explore the sizeofexpressions ?
4909  break;
4910  };
4911  default:
4912  pips_internal_error("Unexpected or unimplemented tad=%d", syntax_tag(s));
4913  break;
4914  }
4915  return tf;
4916 }
#define pips_internal_error
Definition: misc-local.h:149
#define syntax_tag(x)
Definition: ri.h:2727
#define sizeofexpression_expression(x)
Definition: ri.h:2409
#define syntax_cast(x)
Definition: ri.h:2739
#define syntax_application(x)
Definition: ri.h:2748
@ is_syntax_range
Definition: ri.h:2692
@ is_syntax_application
Definition: ri.h:2697
@ is_syntax_cast
Definition: ri.h:2694
@ is_syntax_call
Definition: ri.h:2693
@ is_syntax_va_arg
Definition: ri.h:2698
@ is_syntax_reference
Definition: ri.h:2691
@ is_syntax_sizeofexpression
Definition: ri.h:2695
@ is_syntax_subscript
Definition: ri.h:2696
#define cast_expression(x)
Definition: ri.h:747
#define application_arguments(x)
Definition: ri.h:510
#define subscript_indices(x)
Definition: ri.h:2563
#define syntax_sizeofexpression(x)
Definition: ri.h:2742
#define sizeofexpression_expression_p(x)
Definition: ri.h:2407
#define syntax_call(x)
Definition: ri.h:2736
#define subscript_array(x)
Definition: ri.h:2561
#define application_function(x)
Definition: ri.h:508
#define syntax_subscript(x)
Definition: ri.h:2745
#define call_arguments(x)
Definition: ri.h:711
transformer expressions_to_transformer(list expl, transformer pre)
Compute the transformer associated to a list of expressions such as "i=0, j = 1;".
Definition: expression.c:5722
transformer any_expression_side_effects_to_transformer(expression e, transformer p, bool is_internal __attribute__((unused)))
The value of the expression is irrelevant, but its sub-expressions may generate a transformer.
Definition: expression.c:4845
transformer any_expressions_side_effects_to_transformer(list el, transformer p, bool is_internal)
same as any_expression_side_effects_to_transformer() but for a list of expressions
Definition: expression.c:4921

References any_expressions_side_effects_to_transformer(), application_arguments, application_function, call_arguments, cast_expression, expression_syntax, expressions_to_transformer(), free_transformer(), is_syntax_application, is_syntax_call, is_syntax_cast, is_syntax_range, is_syntax_reference, is_syntax_sizeofexpression, is_syntax_subscript, is_syntax_va_arg, pips_internal_error, reference_indices, sizeofexpression_expression, sizeofexpression_expression_p, subscript_array, subscript_indices, syntax_application, syntax_call, syntax_cast, syntax_reference, syntax_sizeofexpression, syntax_subscript, syntax_tag, transformer_combine(), and transformer_undefined.

Referenced by any_expressions_side_effects_to_transformer(), and safe_any_expression_side_effects_to_transformer().

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

◆ any_expression_to_transformer()

transformer any_expression_to_transformer ( entity  v,
expression  expr,
transformer  pre,
bool  is_internal 
)

A set of functions to compute the transformer associated to an expression evaluated in a given context.

The choices are:

  1. Do I need the value of the expression? It seems strange but in some cases, the expression value is discarded. See for instance the C for construct.

Keyword: "any" implies that the expression value is needed

  1. In case of failure, do I need an approximate transformer based on memory effects or an undefined transformer because I want to try something else?

Keyword: "safe" implies that effects are used and that no undefined transformer is returned.

  1. In case of interprocedural call, am I ready to fail? This might be useful for the libraries "control" and "effects", but is not implemented yet.

Suggested keyword: "light"

  1. Conditional expressions require specific treatment because the bool analysis is not well linked to the integer analysis and because C uses implicit conditions: if(n) means if(n!=0).
  2. Expression lists are a special case of expression. This function may return an undefined transformers if it fails to capture the semantics of expr in the polyhedral framework.

Should basic of expression take care of this?

Assume v is a value

If we are here, it should be an enum type...

Constants, at least, could be typed coerced

Redundant with explicit type coercion also available in PIPS

To be done later

PIPS does not represent negative constants: call to unary_minus

PIPS does not represent complex constants: call to CMPLX

Only constant string are processed

The overloading is supposed to have been lifted by basic_of_expression()

enum type are analyzed like int

This function is called from the region analysis, with extended expressions such as "*", the unbounded expression.

It might be interesting to go further in case the comma operator is used

No need to link the returned value as it must be cast to the proper type.

tf may be transformer_undefined when no information is derived

Parameters
exprxpr
prere
is_internals_internal

Definition at line 4993 of file expression.c.

4998 {
5000  basic be = basic_of_expression(expr);
5002 
5003  if(basic_typedef_p(be)) {
5004  entity te = basic_typedef(be);
5005  type nte = ultimate_type(entity_type(te));
5006 
5007  pips_assert("nte is of type variable", type_variable_p(nte));
5008 
5009  /* Should basic of expression take care of this? */
5010  pips_debug(8, "Fix basic be\n");
5011 
5012  free_basic(be);
5014  }
5015 
5016  ifdebug(8) {
5017  pips_debug(8, "begin for entity %s of type %s and %s expression ",
5018  entity_local_name(v),
5019  basic_to_string(bv), basic_to_string(be));
5020  print_expression(expr);
5021  }
5022 
5023  /* Assume v is a value */
5024  if( (basic_tag(bv)==basic_tag(be))
5025  || (basic_float_p(bv) && basic_int_p(be))
5026  || (basic_derived_p(bv) && basic_int_p(be))
5027  || (basic_derived_p(be) && basic_int_p(bv))
5028  || (basic_logical_p(bv) && basic_int_p(be))
5029  || (basic_logical_p(be) && basic_int_p(bv))
5030  || (basic_pointer_p(bv) && basic_int_p(be))) {
5031  switch(basic_tag(be)) {
5032  case is_basic_int:
5033  if(integer_analyzed_p()) {
5034  if(basic_int_p(bv)) {
5035  tf = integer_expression_to_transformer(v, expr, pre, is_internal);
5036  }
5037  else if(basic_derived_p(bv)) {
5038  /* If we are here, it should be an enum type... */
5039  tf = integer_expression_to_transformer(v, expr, pre, is_internal);
5040  }
5041  else if(basic_logical_p(bv)) {
5042  tf = logical_expression_to_transformer(v, expr, pre, is_internal);
5043  }
5044  else if(basic_pointer_p(bv)) {
5045  //tf = integer_expression_to_transformer(v, expr, pre, is_internal);
5046  // arithmetic for pointer
5047  if(pointer_analyzed_p())
5048  tf = pointer_expression_to_transformer(v, expr, pre, is_internal);
5049  }
5050  else {
5051  semantics_user_warning("Integer expression assigned to float value\n"
5052  "Apply PIPS type checker for better results\n");
5053  /* Constants, at least, could be typed coerced */
5054  /* Redundant with explicit type coercion also available in PIPS */
5055  /* To be done later */
5056  }
5057  }
5058  break;
5059  case is_basic_logical:
5060  if(basic_logical_p(bv) && boolean_analyzed_p())
5061  tf = logical_expression_to_transformer(v, expr, pre, is_internal);
5062  else if(basic_int_p(bv)) { // We should check that integers are analyzed...
5063  tf = integer_expression_to_transformer(v, expr, pre, is_internal);
5064  }
5065  break;
5066  case is_basic_float:
5067  /* PIPS does not represent negative constants: call to unary_minus */
5068  if(float_analyzed_p())
5069  tf = float_expression_to_transformer(v, expr, pre, is_internal);
5070  break;
5071  case is_basic_pointer:
5072  if(pointer_analyzed_p())
5073  tf = pointer_expression_to_transformer(v, expr, pre, is_internal);
5074  break;
5075  case is_basic_complex:
5076  /* PIPS does not represent complex constants: call to CMPLX */
5077  break;
5078  case is_basic_string:
5079  /* Only constant string are processed */
5080  if(string_analyzed_p())
5081  tf = string_expression_to_transformer(v, expr);
5082  break;
5083  case is_basic_overloaded: {
5084  /* The overloading is supposed to have been lifted by
5085  basic_of_expression() */
5087  tf = transformer_identity();
5088  else
5089  pips_internal_error("illegal overloaded type for an expression");
5090  break;
5091  }
5092  case is_basic_derived: {
5093  entity de = basic_derived(be);
5094  type det = ultimate_type(entity_type(de));
5095  if(type_enum_p(det)) {
5096  /* enum type are analyzed like int */
5097  tf = integer_expression_to_transformer(v, expr, pre, is_internal);
5098  }
5099  else {
5100  pips_internal_error("entities of type \"derived\" that are not \"enum\" cannot be analyzed");
5101  }
5102  break;
5103  }
5104  case is_basic_typedef:
5105  pips_internal_error("entities of type \"typedef\" cannot be analyzed");
5106  break;
5107  default:
5108  pips_internal_error("unknown basic b=%d", basic_tag(be));
5109  }
5110  }
5111  else {
5112  if(!basic_overloaded_p(be)) {
5113  semantics_user_warning("Implicit type coercion between variable \"%s\" of type \"%s\" and "
5114  "expression \"%s\" of type \"%s\" may reduce semantic analysis accuracy.\n"
5115  "You might apply 'type_checker' to explicit all type coercions.\n",
5116  entity_user_name(v),
5117  basic_to_string(bv),
5118  expression_to_string(expr),
5119  basic_to_string(be));
5120  }
5121  else if(!unbounded_expression_p(expr)) {
5122  /* This function is called from the region analysis, with
5123  * extended expressions such as "*", the unbounded
5124  * expression.
5125  */
5127  "expression \"%s\" with overloaded type may reduce semantic analysis accuracy for variable \"%s\" of type \"%s\".\n"
5128  "You might apply 'type_checker' to explicit all type coercions.\n",
5129  expression_to_string(expr),
5130  entity_user_name(v),
5131  basic_to_string(bv));
5132  }
5133  /* It might be interesting to go further in case the comma operator is used */
5134  if(comma_expression_p(expr)) {
5135  call c = syntax_call(expression_syntax(expr));
5136  list expr_l = call_arguments(c);
5137 
5138  /* No need to link the returned value as it must be cast to the
5139  proper type. */
5140  tf = expressions_to_transformer(expr_l, pre);
5141  }
5142  }
5143 
5144  /* tf may be transformer_undefined when no information is derived */
5145  ifdebug(1) {
5146  if(!transformer_undefined_p(pre))
5147  pips_assert("No obvious aliasing between tf and pre", tf!=pre);
5148  }
5149  pips_debug(8, "end with tf=%p\n", tf);
5150 
5151  return tf;
5152 }
basic copy_basic(basic p)
BASIC.
Definition: ri.c:104
void free_basic(basic p)
Definition: ri.c:107
void print_expression(expression e)
no file descriptor is passed to make is easier to use in a debugging stage.
Definition: expression.c:58
string basic_to_string(basic)
Definition: type.c:87
#define ENTITY_CONTINUE_P(e)
bool expression_call_p(expression e)
Definition: expression.c:415
call expression_call(expression e)
Definition: expression.c:445
bool comma_expression_p(expression e)
Definition: expression.c:830
bool unbounded_expression_p(expression e)
Definition: expression.c:4329
basic basic_of_expression(expression)
basic basic_of_expression(expression exp): Makes a basic of the same basic as the expression "exp".
Definition: type.c:1383
type ultimate_type(type)
Definition: type.c:3466
#define type_enum_p(x)
Definition: ri.h:2968
@ is_basic_derived
Definition: ri.h:579
@ is_basic_string
Definition: ri.h:576
@ is_basic_float
Definition: ri.h:572
@ is_basic_pointer
Definition: ri.h:578
@ is_basic_overloaded
Definition: ri.h:574
@ is_basic_int
Definition: ri.h:571
@ is_basic_logical
Definition: ri.h:573
@ is_basic_typedef
Definition: ri.h:580
@ is_basic_complex
Definition: ri.h:575
#define basic_int_p(x)
Definition: ri.h:614
#define call_function(x)
Definition: ri.h:709
#define basic_derived(x)
Definition: ri.h:640
#define basic_typedef_p(x)
Definition: ri.h:641
#define basic_tag(x)
Definition: ri.h:613
#define type_variable(x)
Definition: ri.h:2949
#define basic_pointer_p(x)
Definition: ri.h:635
#define basic_derived_p(x)
Definition: ri.h:638
#define basic_overloaded_p(x)
Definition: ri.h:623
#define basic_typedef(x)
Definition: ri.h:643
#define type_variable_p(x)
Definition: ri.h:2947
#define variable_basic(x)
Definition: ri.h:3120
#define basic_logical_p(x)
Definition: ri.h:620
#define basic_float_p(x)
Definition: ri.h:617
transformer pointer_expression_to_transformer(entity v, expression expr, transformer pre, bool is_internal)
Definition: expression.c:4582
transformer string_expression_to_transformer(entity v, expression rhs)
Definition: expression.c:3994
transformer integer_expression_to_transformer(entity v, expression expr, transformer pre, bool is_internal)
Do check wrt to value mappings...
Definition: expression.c:3476
transformer float_expression_to_transformer(entity v, expression rhs, transformer pre, bool is_internal)
Definition: expression.c:4153
transformer logical_expression_to_transformer(entity v, expression rhs, transformer pre, bool is_internal)
Could be used to compute preconditions too.
Definition: expression.c:3938
bool pointer_analyzed_p(void)
Definition: value.c:325
bool integer_analyzed_p(void)
Definition: value.c:300
bool boolean_analyzed_p(void)
Definition: value.c:305
bool float_analyzed_p(void)
Definition: value.c:315
bool string_analyzed_p(void)
Definition: value.c:310

References basic_derived, basic_derived_p, basic_float_p, basic_int_p, basic_logical_p, basic_of_expression(), basic_overloaded_p, basic_pointer_p, basic_tag, basic_to_string(), basic_typedef, basic_typedef_p, boolean_analyzed_p(), call_arguments, call_function, comma_expression_p(), copy_basic(), ENTITY_CONTINUE_P, entity_local_name(), entity_type, entity_user_name(), expression_call(), expression_call_p(), expression_syntax, expression_to_string(), expressions_to_transformer(), float_analyzed_p(), float_expression_to_transformer(), free_basic(), ifdebug, integer_analyzed_p(), integer_expression_to_transformer(), is_basic_complex, is_basic_derived, is_basic_float, is_basic_int, is_basic_logical, is_basic_overloaded, is_basic_pointer, is_basic_string, is_basic_typedef, logical_expression_to_transformer(), pips_assert, pips_debug, pips_internal_error, pointer_analyzed_p(), pointer_expression_to_transformer(), print_expression(), semantics_user_warning, string_analyzed_p(), string_expression_to_transformer(), syntax_call, transformer_identity(), transformer_undefined, transformer_undefined_p, type_enum_p, type_variable, type_variable_p, ultimate_type(), unbounded_expression_p(), and variable_basic.

Referenced by add_formal_to_actual_bindings(), 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_data_to_prec_for_variables(), c_return_to_transformer(), expression_to_transformer(), fortran_user_call_to_transformer(), generic_abs_to_transformer(), generic_minmax_to_transformer(), loop_bound_evaluation_to_transformer(), safe_any_expression_to_transformer(), and unary_minus_operation_to_transformer().

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

◆ any_expressions_side_effects_to_transformer()

transformer any_expressions_side_effects_to_transformer ( list  el,
transformer  p,
bool  is_internal 
)

same as any_expression_side_effects_to_transformer() but for a list of expressions

Parameters
ell
is_internals_internal

Definition at line 4921 of file expression.c.

4922 {
4924  FOREACH(EXPRESSION, e, el) {
4925  transformer etf =
4926  any_expression_side_effects_to_transformer(e, p, is_internal);
4927  if(transformer_undefined_p(tf))
4928  tf = etf;
4929  else {
4930  tf = transformer_combine(tf, etf);
4931  free_transformer(etf);
4932  }
4933  }
4934  return tf;
4935 }
#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

References any_expression_side_effects_to_transformer(), EXPRESSION, FOREACH, free_transformer(), transformer_combine(), transformer_undefined, and transformer_undefined_p.

Referenced by any_expression_side_effects_to_transformer().

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

◆ any_expressions_to_transformer()

transformer any_expressions_to_transformer ( entity  v,
list  expl,
transformer  pre 
)

Compute the transformer associated to a list of expressions such as "i=0, j = 1;".

The value returned is linked to v.

To be merged with the previous function.

el is an over-appoximation; should be replaced by a safe_expression_to_transformer() taking care of computing the precise effects of exp instead of using the effects of expl.

Parameters
explxpl
prere

Definition at line 5754 of file expression.c.

5757 {
5761  expression l_exp = EXPRESSION(CAR(gen_last(expl)));
5762 
5763  FOREACH(EXPRESSION, exp, expl) {
5764  /* el is an over-appoximation; should be replaced by a
5765  safe_expression_to_transformer() taking care of computing the
5766  precise effects of exp instead of using the effects of expl. */
5767  transformer ctf = (exp==l_exp)?
5768  safe_any_expression_to_transformer(v, exp, cpre, false) :
5772 
5773  tf = transformer_combine(tf, ctf);
5774  tf = transformer_normalize(tf, 2);
5775  npre = transformer_apply(ctf, cpre);
5776  npre_r = transformer_range(npre);
5777  npre_r = transformer_normalize(npre_r, 2);
5778  free_transformer(cpre);
5779  free_transformer(npre);
5780  free_transformer(ctf);
5781  cpre = npre_r;
5782  }
5783  free_transformer(cpre);
5784  return tf;
5785 }
list gen_last(list l)
Return the last element of a list.
Definition: list.c:578
transformer safe_expression_to_transformer(expression exp, transformer pre)
Definition: expression.c:5307
transformer transformer_normalize(transformer t, int level)
Eliminate (some) rational or integer redundancy.
Definition: transformer.c:932
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207

References CAR, exp, EXPRESSION, FOREACH, free_transformer(), gen_last(), safe_any_expression_to_transformer(), safe_expression_to_transformer(), transformer_apply(), transformer_combine(), transformer_identity(), transformer_normalize(), transformer_range(), transformer_undefined, and transformer_undefined_p.

Referenced by integer_call_expression_to_transformer(), and pointer_call_expression_to_transformer().

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

◆ assign_operation_to_transformer()

transformer assign_operation_to_transformer ( entity  val,
expression  lhs,
expression  rhs,
transformer  pre 
)

Returns an undefined transformer in case of failure.

&& integer_scalar_entity_p(e)

Parameters
valal
lhshs
rhshs
prere

Definition at line 2737 of file expression.c.

2741 {
2743 
2744  pips_debug(8,"begin\n");
2745 
2746  if(expression_reference_p(lhs)) {
2748 
2749  if(entity_has_values_p(e) /* && integer_scalar_entity_p(e) */) {
2750  entity ev = entity_to_new_value(e);
2751  //transformer teq = simple_equality_to_transformer(val, ev, true);
2752  tf = assigned_expression_to_transformer(ev, rhs, pre);
2753  if(!transformer_undefined_p(tf))
2754  tf = transformer_add_equality(tf, val, ev);
2755  //tf = transformer_combine(tf, teq);
2756  //free_transformer(teq);
2757  }
2758  }
2759 
2760  pips_debug(6,"return tf=%lx\n", (unsigned long)tf);
2761  ifdebug(6) (void) dump_transformer(tf);
2762  pips_debug(8,"end\n");
2763  return tf;
2764 }
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
transformer assigned_expression_to_transformer(entity v, expression expr, transformer pre)
transformer assigned_expression_to_transformer(entity e, expression expr, list ef): returns a transfo...

References assigned_expression_to_transformer(), dump_transformer, entity_has_values_p(), entity_to_new_value(), expression_reference_p(), expression_syntax, ifdebug, pips_debug, reference_variable, syntax_reference, transformer_add_equality(), transformer_undefined, and transformer_undefined_p.

Referenced by float_binary_operation_to_transformer(), integer_binary_operation_to_transformer(), logical_binary_function_to_transformer(), and pointer_binary_operation_to_transformer().

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

◆ bitwise_xor_to_transformer()

transformer bitwise_xor_to_transformer ( entity  v,
list  args,
transformer  pre 
)

returns the transformer associated to a C bitwise xor, ^, applied to two integer argument, when meaningful, and transformer_undefined otherwise.

Effects must be used at a higher level to fall back on a legal transformer.

Parameters
vis the value associated to the expression
argsis assumed to have only one expression element of type int negated by !
preis the current precondition

Something can be done when both arguments have values in [0,1], when both arguments have known numerical values, when both arguments have the same value,... However, all this tests imply lots time consuming projections for a limited result... Unless somebody uses XOR to flip-flop between arrays... for instance to bother Sven Verdoolaege:-). A logical not might be more useful for this:-).

The two values are know at compile time

The two values can be interpreted as booleans

Code about cut-and-pasted from logical_binary_operation_to_transformer()

The two arguments may be equal because they are the same expression and the xor is used to generate a zero or because they have the same value.

Since the difference is zero the two values are equal

Parameters
argsrgs
prere

Definition at line 5619 of file expression.c.

5622 {
5623  /* Something can be done when both arguments have values in [0,1],
5624  when both arguments have known numerical values, when both
5625  arguments have the same value,... However, all this
5626  tests imply lots time consuming projections for a limited
5627  result... Unless somebody uses XOR to flip-flop between
5628  arrays... for instance to bother Sven Verdoolaege:-). A logical
5629  not might be more useful for this:-). */
5630  expression le1 = EXPRESSION(CAR(args));
5631  //basic be1 = basic_of_expression(le1);
5632  expression le2 = EXPRESSION(CAR(CDR(args)));
5633  //basic be2 = basic_of_expression(le2);
5635 
5636  //if(basic_int_p(be1) && basic_int_p(be2)) {
5638  // FI: Even with the "in context" property, the precondition is
5639  // not integrated into the transformer...
5640  transformer tf1 = safe_any_expression_to_transformer(tmp_v1, le1, pre, true);
5641  //transformer tfr1 = transformer_range(tf1);
5642  transformer tfr1 = transformer_apply(tf1, pre);
5643  intptr_t lb1, ub1;
5645  transformer tf2 = safe_any_expression_to_transformer(tmp_v2, le2, pre, true);
5646  // transformer tfr2 = transformer_range(tf2);
5647  transformer tfr2 = transformer_apply(tf2, pre);
5648  intptr_t lb2, ub2;
5649 
5650  if(precondition_minmax_of_value(tmp_v1, tfr1, &lb1, &ub1)
5651  && precondition_minmax_of_value(tmp_v2, tfr2, &lb2, &ub2)) {
5652  if(lb1==ub1 && lb2==ub2) {
5653  /* The two values are know at compile time */
5654  tf = transformer_identity();
5655  tf = transformer_add_equality_with_integer_constant(tf, v, lb1 ^ lb2);
5656  }
5657  else if(0<=lb1 && ub1 <= 1 && 0<=lb2 && ub2 <= 1) {
5658  tf = transformer_identity();
5659  /* The two values can be interpreted as booleans */
5660  /* Code about cut-and-pasted from
5661  logical_binary_operation_to_transformer() */
5662  Pvecteur eq1 = vect_new((Variable) v, VALUE_ONE);
5663  vect_add_elem(&eq1, (Variable) tmp_v1, VALUE_MONE);
5664  vect_add_elem(&eq1, (Variable) tmp_v2, VALUE_MONE);
5665 
5666  Pvecteur eq2 = vect_new((Variable) v, VALUE_ONE);
5667  vect_add_elem(&eq2, (Variable) tmp_v1, VALUE_ONE);
5668  vect_add_elem(&eq2, (Variable) tmp_v2, VALUE_ONE);
5670 
5671  Pvecteur eq3 = vect_new((Variable) v, VALUE_MONE);
5672  vect_add_elem(&eq3, (Variable) tmp_v1, VALUE_ONE);
5673  vect_add_elem(&eq3, (Variable) tmp_v2, VALUE_MONE);
5674 
5675  Pvecteur eq4 = vect_new((Variable) v, VALUE_MONE);
5676  vect_add_elem(&eq4, (Variable) tmp_v1, VALUE_MONE);
5677  vect_add_elem(&eq4, (Variable) tmp_v2, VALUE_ONE);
5678 
5679  tf = transformer_inequality_add(tf, eq1);
5680  tf = transformer_inequality_add(tf, eq2);
5681  tf = transformer_inequality_add(tf, eq3);
5682  tf = transformer_inequality_add(tf, eq4);
5683  }
5684  }
5685  if(transformer_undefined_p(tf)) {
5686  /* The two arguments may be equal because they are the same
5687  expression and the xor is used to generate a zero or because
5688  they have the same value. */
5689  if(expression_equal_p(le1, le2)) {
5690  tf = transformer_identity();
5692  }
5693  else {
5694  transformer tfr1 = transformer_range(tf1);
5695  transformer tfr2 = transformer_range(tf2);
5696  transformer tfi = transformer_intersection(tfr1, tfr2);
5698  Pvecteur eq = vect_new((Variable) tmp_d, VALUE_ONE);
5699  vect_add_elem(&eq, (Variable) tmp_v1, VALUE_MONE);
5700  vect_add_elem(&eq, (Variable) tmp_v2, VALUE_ONE);
5701  tfi = transformer_equality_add(tfi, eq);
5702  intptr_t lbd, ubd;
5703 
5704  if(precondition_minmax_of_value(tmp_d, tfi, &lbd, &ubd)) {
5705  if(lbd==0 && ubd==0) {
5706  /* Since the difference is zero the two values are equal */
5707  tf = transformer_identity();
5709  }
5710  }
5711  }
5712  }
5713  //}
5714  //free_basic(be1), free_basic(be2);
5715  free_transformer(tfr1), free_transformer(tfr2);
5716  return tf;
5717 }
#define VALUE_MONE
transformer transformer_inequality_add(transformer tf, Pvecteur i)
Definition: basic.c:375
transformer transformer_add_equality_with_integer_constant(transformer tf, entity v, long long int cst)
Add an equality between a value and an integer constant: v==cst.
Definition: basic.c:450
transformer transformer_equality_add(transformer tf, Pvecteur i)
Definition: basic.c:383
bool expression_equal_p(expression e1, expression e2)
Syntactic equality e1==e2.
Definition: expression.c:1347
bool precondition_minmax_of_value(entity val, transformer tr, intptr_t *pmin, intptr_t *pmax)
compute integer bounds pmax, pmin of value val under preconditions tr require value mappings set !
Definition: expression.c:5790
#define intptr_t
Definition: stdint.in.h:294
transformer transformer_intersection(transformer t1, transformer t2)
tf is a new transformer that receives the constraints in t1 and t2.
Definition: transformer.c:600
entity make_local_temporary_integer_value_entity(void)
Definition: value.c:629
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.

References CAR, CDR, eq, EXPRESSION, expression_equal_p(), free_transformer(), intptr_t, make_local_temporary_integer_value_entity(), precondition_minmax_of_value(), safe_any_expression_to_transformer(), TCST, transformer_add_equality_with_integer_constant(), transformer_apply(), transformer_equality_add(), transformer_identity(), transformer_inequality_add(), transformer_intersection(), transformer_range(), transformer_undefined, transformer_undefined_p, VALUE_MONE, VALUE_ONE, vect_add_elem(), and vect_new().

Referenced by integer_call_expression_to_transformer().

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

◆ condition_to_transformer()

transformer condition_to_transformer ( expression  cond,
transformer  pre,
bool  veracity 
)

To capture side effects and to add C twist for numerical conditions.

Argument pre may be undefined.

Beware of tricky conditions using the comma or the conditional operator, although they should be handled as the default case, using effects.

upwards should be set to false when computing preconditions (but we have no way to know) or when computing tramsformers in context. And set to true in other cases. upwards is a way to gain execution time at the expense of precision. This speed/accuracy tradeoff has evolved with CPU technology.

If a comma operator is used, the test is the last expression

FI: quid of a conditional operator? e.g. "x>0?1<m:1<n"

FI: quid of assignment operator? e.g. "i = j = k = 1"

FI: we probably need a function tcond = expression_to_condition(cond)

C comparison operators return an integer value

FI: not good when side effects in cond

In case, there are side-effects in the condition. This is very unlikely for standard code and should be simplified with a test to transformer_identity_p(tf)

Make sure you can handle this kind of variable.

This test is added for Semantics-New/transformer01.c which tests a pointer. The underlying bug may still be there when pointers are analyzed by PIPS.

tmpv != 0

tmpv==0

Not yet? We may be in a = c? x : y; or in e1, e2,...; Does it matter?

May be dangerous if this routine is called internally to another routine using temporary variables...

reset_temporary_value_counter();

Parameters
condond
prere
veracityeracity

Definition at line 5348 of file expression.c.

5351 {
5353 
5354  if(expression_cast_p(cond)) {
5356  tf = condition_to_transformer(nc, pre, veracity);
5357  }
5358  else {
5359  //list el = expression_to_proper_effects(cond);
5361  transformer safe_pre = transformer_undefined_p(pre)?
5363  transformer_range(pre);
5364  basic eb = basic_of_expression(cond);
5365  bool relation_p = false;
5366  /* upwards should be set to false when computing preconditions (but
5367  we have no way to know) or when computing tramsformers in
5368  context. And set to true in other cases. upwards is a way to gain
5369  execution time at the expense of precision. This speed/accuracy
5370  tradeoff has evolved with CPU technology. */
5371  bool upwards = false;
5372  expression tcond = cond; // By default; not true for the comma operations
5373 
5374  /* If a comma operator is used, the test is the last expression */
5375  /* FI: quid of a conditional operator? e.g. "x>0?1<m:1<n" */
5376  /* FI: quid of assignment operator? e.g. "i = j = k = 1" */
5377  /* FI: we probably need a function tcond = expression_to_condition(cond) */
5378  if(expression_call_p(cond)) {
5379  call c = syntax_call(expression_syntax(cond));
5380  entity op = call_function(c);
5381  if(ENTITY_COMMA_P(op)) {
5382  list args = call_arguments(c);
5383  tcond = EXPRESSION(CAR(gen_last(args)));
5384  tf = safe_expression_to_transformer(cond, pre);
5385  }
5386  }
5387  if(transformer_undefined_p(tf)) {
5388  tf = transformer_identity();
5389  }
5390 
5391  /* C comparison operators return an integer value */
5392  if(!basic_logical_p(eb) && expression_call_p(tcond)) {
5394 
5395  relation_p = ENTITY_LOGICAL_OPERATOR_P(op);
5396  //relation_p = ENTITY_RELATIONAL_OPERATOR_P(op);
5397  }
5398 
5399  if(basic_logical_p(eb)) {
5400  // entity tmpv = make_local_temporary_value_entity_with_basic(eb);
5401  //tf = logical_expression_to_transformer(tmpv, cond, safe_pre, true);
5402  //tf = transformer_add_condition_information_updown
5403  // (transformer_identity(), cond, safe_pre, veracity, upwards);
5404  /* FI: not good when side effects in cond */
5405  //tf = transformer_add_condition_information_updown
5406  // (copy_transformer(safe_pre), cond, safe_pre, veracity, upwards);
5408  (tf, tcond, safe_pre, veracity, upwards);
5409  tf = transformer_apply(ctf, safe_pre);
5410  free_transformer(ctf);
5411  }
5412  else if(relation_p) {
5413  //tf = transformer_add_condition_information_updown
5414  // (transformer_identity(), cond, safe_pre, veracity, upwards);
5415  //tf = transformer_add_condition_information_updown
5416  // (copy_transformer(safe_pre), cond, safe_pre, veracity, upwards);
5417  /* In case, there are side-effects in the condition. This is very
5418  unlikely for standard code and should be simplified with a
5419  test to transformer_identity_p(tf) */
5420  transformer new_pre = transformer_apply(tf, safe_pre);
5421  transformer new_pre_r = transformer_range(new_pre);
5422  new_pre_r = transformer_normalize(new_pre_r, 2);
5424  (transformer_identity(), tcond, new_pre_r, veracity, upwards);
5426  ctf = transformer_normalize(ctf, 2);
5427  tf = transformer_combine(tf, ctf);
5428  free_transformer(ctf);
5429  free_transformer(new_pre);
5430  free_transformer(new_pre_r);
5431  }
5432  else {
5433  /* Make sure you can handle this kind of variable.
5434 
5435  This test is added for Semantics-New/transformer01.c which
5436  tests a pointer. The underlying bug may still be there when
5437  pointers are analyzed by PIPS.
5438  */
5439  if(analyzed_basic_p(eb)) {
5441  transformer ctf = safe_any_expression_to_transformer(tmpv, tcond, safe_pre, true);
5442  tf = transformer_combine(tf, ctf);
5443  if(veracity) {
5444  /* tmpv != 0 */
5447 
5448  ifdebug(8) {
5449  fprintf(stderr, "tf_plus %p:\n", tf_plus);
5450  dump_transformer(tf_plus);
5451  fprintf(stderr, "tf_minus %p:\n", tf_minus);
5452  dump_transformer(tf_minus);
5453  }
5454 
5455  free_transformer(tf);
5456  tf = transformer_convex_hull(tf_plus, tf_minus);
5457  free_transformer(tf_plus);
5458  free_transformer(tf_minus);
5459  }
5460  else {
5461  /* tmpv==0 */
5462  tf = transformer_add_sign_information(tf, tmpv, 0);
5463  }
5464  }
5465  }
5466 
5467  if(transformer_undefined_p(tf))
5468  tf = effects_to_transformer(el);
5469  else {
5470  /* Not yet? We may be in a = c? x : y; or in e1, e2,...; Does it matter? */
5472  //reset_temporary_value_counter();
5473  }
5474  /* May be dangerous if this routine is called internally to another
5475  routine using temporary variables... */
5476  /* reset_temporary_value_counter(); */
5477 
5478  gen_full_free_list(el);
5479  free_basic(eb);
5480  free_transformer(safe_pre);
5481  }
5482 
5483  return tf;
5484 }
transformer copy_transformer(transformer p)
TRANSFORMER.
Definition: ri.c:2613
transformer transformer_add_sign_information(transformer tf, entity v, int v_sign)
CHANGE THIS NAME: no loop index please, it's not directly linked to loops!!!
Definition: basic.c:200
list expression_to_proper_constant_path_effects(expression)
#define ENTITY_COMMA_P(e)
#define ENTITY_LOGICAL_OPERATOR_P(e)
Attention : This definition is different with the Fortran Standard where the logical operators are th...
bool expression_cast_p(expression e)
Definition: expression.c:450
cast expression_cast(expression e)
Definition: expression.c:455
transformer effects_to_transformer(list e)
list of effects
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
static transformer transformer_add_condition_information_updown(transformer, expression, transformer, bool, bool)
call transformer_add_condition_information_updown() recursively on both sub-expressions if veracity =...
Definition: expression.c:961
transformer transformer_temporary_value_projection(transformer tf)
Definition: transformer.c:1149
bool analyzed_basic_p(basic)
The basic corresponds to one of the analyzed types.
Definition: value.c:337
entity make_local_temporary_value_entity_with_basic(basic)
Definition: value.c:620

References analyzed_basic_p(), basic_logical_p, basic_of_expression(), call_arguments, call_function, CAR, cast_expression, copy_transformer(), dump_transformer, effects_to_transformer(), ENTITY_COMMA_P, ENTITY_LOGICAL_OPERATOR_P, EXPRESSION, expression_call_p(), expression_cast(), expression_cast_p(), expression_syntax, expression_to_proper_constant_path_effects(), fprintf(), free_basic(), free_transformer(), gen_full_free_list(), gen_last(), ifdebug, make_local_temporary_value_entity_with_basic(), safe_any_expression_to_transformer(), safe_expression_to_transformer(), syntax_call, transformer_add_condition_information_updown(), transformer_add_sign_information(), transformer_apply(), transformer_combine(), transformer_convex_hull(), transformer_identity(), transformer_normalize(), transformer_range(), transformer_temporary_value_projection(), transformer_undefined, and transformer_undefined_p.

Referenced by any_conditional_to_transformer(), complete_forloop_transformer(), complete_forloop_transformer_list(), complete_repeatloop_transformer_list(), conditional_to_transformer(), forloop_to_postcondition(), forloop_to_transformer(), intrinsic_to_transformer(), intrinsic_to_transformer_list(), new_complete_whileloop_transformer_list(), new_whileloop_to_k_transformer(), new_whileloop_to_transformer(), repeatloop_to_postcondition(), repeatloop_to_transformer(), simplify_boolean_expression_with_precondition(), test_to_postcondition(), test_to_transformer(), test_to_transformer_list(), and whileloop_to_postcondition().

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

◆ conditional_to_transformer()

transformer conditional_to_transformer ( expression  cond,
expression  te,
expression  fe,
transformer  pre,
list  ef 
)

FI: not too smart to start with the special case with no value returned, just side-effects...

Parameters
condond
tee
fee
prere
eff

Definition at line 5488 of file expression.c.

5493 {
5495  transformer ttf = condition_to_transformer(cond, pre, true);
5496  transformer t_pre = transformer_apply(ttf, pre);
5497  transformer t_pre_r = transformer_range(t_pre);
5498  transformer tet = safe_expression_to_transformer(te, t_pre_r);
5499  transformer ftf = condition_to_transformer(cond, pre, false);
5500  transformer f_pre = transformer_apply(ftf, pre);
5501  transformer f_pre_r = transformer_range(f_pre);
5502  transformer fet = safe_expression_to_transformer(fe, f_pre_r);
5503 
5504  ttf = transformer_combine(ttf, tet);
5505  ftf = transformer_combine(ftf, fet);
5506  tf = transformer_convex_hull(ttf, ftf);
5507 
5508  free_transformer(ttf);
5509  free_transformer(ftf);
5510  free_transformer(tet);
5511  free_transformer(fet);
5512  free_transformer(t_pre_r);
5513  free_transformer(f_pre_r);
5514  free_transformer(t_pre);
5515  free_transformer(f_pre);
5516 
5517  if(transformer_undefined_p(tf))
5518  tf = effects_to_transformer(ef);
5519  return tf;
5520 }

References condition_to_transformer(), effects_to_transformer(), free_transformer(), safe_expression_to_transformer(), transformer_apply(), transformer_combine(), transformer_convex_hull(), transformer_range(), transformer_undefined, and transformer_undefined_p.

Referenced by intrinsic_to_transformer(), and intrinsic_to_transformer_list().

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

◆ constant_to_transformer()

static transformer constant_to_transformer ( entity  v,
expression  rhs 
)
static

the rhs is a call to a constant function

Implicitly sufficient length or implicit padding with SPACEs

Take the prefix of the constant. Expect problems with PIPS quotes...

This is not a constant string

Definition at line 645 of file expression.c.

647 {
649  syntax srhs = expression_syntax(rhs);
650 
651  pips_debug(9, "Begin for entity %s",
652  entity_local_name(v));
653 
654  /* the rhs is a call to a constant function */
655  if(syntax_call_p(srhs)) {
657 
658  pips_debug(9, " and constant %s\n", module_local_name(f));
659 
660  if(entity_constant_p(f)) {
661  basic fb = entity_basic(f);
662 
663  if(basic_string_p(fb)) {
664  basic vb = entity_basic(v);
665  if(basic_string_p(vb)) {
666  int llhs = string_type_size(vb);
667  int lrhs = string_type_size(fb);
668 
669  if(llhs==-1 || llhs >= lrhs) {
670  /* Implicitly sufficient length or implicit padding with SPACEs */
671  tf = simple_equality_to_transformer(v, f, false);
672  }
673  else {
674  /* Take the prefix of the constant. Expect problems with PIPS quotes... */
675  string n = malloc(llhs+3);
677 
678  n = strncpy(n, entity_local_name(f), llhs+1);
679  *(n+llhs+1) = *n;
680  pips_assert("A simple or a double quote is used", *n=='"' || *n=='\'');
681  *(n+llhs+2) = 0;
682  f1 = make_constant_entity(n, is_basic_string, llhs);
683  tf = simple_equality_to_transformer(v, f1, false);
684  }
685  }
686  else {
687  pips_user_error("CHARACTER variable assigned a non CHARACTER constant, \"%s\"\n",
689  }
690  }
691  else {
692  /* This is not a constant string */
693  int i;
694  if(integer_constant_p(f, &i) && i==0) {
695  tf = transformer_identity();
697  }
698  else if(float_constant_p(f) && float_constant_to_double(f)==0.) {
699  tf = transformer_identity();
701  }
702  else
703  tf = simple_equality_to_transformer(v, f, false);
704  }
705  }
706  }
707 
708  pips_debug(9, "End for entity %s\n",
709  entity_local_name(v));
710 
711  return tf;
712 }
entity make_constant_entity(string name, tag bt, size_t size)
For historical reason, call the Fortran version.
Definition: constant.c:301
double float_constant_to_double(entity c)
Definition: constant.c:639
bool integer_constant_p(entity ent, int *int_p)
Returns the double value associated to a PIPS constant.
Definition: constant.c:542
bool float_constant_p(entity ent)
ent can be either a numerical or a symbolic float constant
Definition: constant.c:487
void * malloc(YYSIZE_T)
#define pips_user_error
Definition: misc-local.h:147
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
#define entity_constant_p(e)
basic entity_basic(entity e)
return the basic associated to entity e if it's a function/variable/constant basic_undefined otherwis...
Definition: entity.c:1380
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
int string_type_size(basic)
Definition: type.c:1047
#define syntax_call_p(x)
Definition: ri.h:2734
#define entity_undefined
Definition: ri.h:2761
#define basic_string_p(x)
Definition: ri.h:629

References basic_string_p, call_function, entity_basic(), entity_constant_p, entity_local_name(), entity_undefined, expression_syntax, f(), float_constant_p(), float_constant_to_double(), integer_constant_p(), is_basic_string, make_constant_entity(), malloc(), module_local_name(), pips_assert, pips_debug, pips_user_error, simple_equality_to_transformer(), string_type_size(), syntax_call, syntax_call_p, transformer_add_equality_with_integer_constant(), transformer_identity(), and transformer_undefined.

Referenced by float_call_expression_to_transformer(), and string_expression_to_transformer().

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

◆ eval_condition_wrt_precondition_p()

bool eval_condition_wrt_precondition_p ( expression  c,
transformer  pre,
bool  veracity 
)
Parameters
prere
veracityeracity

Definition at line 5909 of file expression.c.

5910 {
5911  bool result = false;
5912  transformer f = transformer_dup(pre);
5913 
5914  if(veracity) {
5915  f = precondition_add_condition_information(f, c, pre, false);
5916  }
5917  else {
5918  f = precondition_add_condition_information(f, c, pre, true);
5919  }
5920 
5921  result = transformer_empty_p(f);
5922 
5923  return result;
5924 }
transformer transformer_dup(transformer t_in)
transformer package - basic routines
Definition: basic.c:49
transformer precondition_add_condition_information(transformer pre, expression c, transformer context, bool veracity)
context might be derivable from pre as transformer_range(pre) but this is sometimes very computationa...
Definition: expression.c:1111
bool transformer_empty_p(transformer t)
If true is returned, the transformer certainly is empty.
Definition: transformer.c:2455

References f(), precondition_add_condition_information(), transformer_dup(), and transformer_empty_p().

Referenced by false_condition_wrt_precondition_p(), and true_condition_wrt_precondition_p().

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

◆ expression_effects_to_transformer()

transformer expression_effects_to_transformer ( expression  expr)
Parameters
exprxpr

Definition at line 3465 of file expression.c.

3466 {
3467  //list el = expression_to_proper_effects(expr);
3470 
3471  gen_full_free_list(el);
3472  return tf;
3473 }

References effects_to_transformer(), expression_to_proper_constant_path_effects(), and gen_full_free_list().

Referenced by integer_expression_to_transformer(), safe_any_expression_side_effects_to_transformer(), safe_assigned_expression_to_transformer(), safe_integer_expression_to_transformer(), transformer_add_call_condition_information_updown(), and transformer_add_condition_information_updown().

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

◆ expression_multiply_sizeof_to_transformer()

static transformer expression_multiply_sizeof_to_transformer ( entity  v,
expression  e1,
transformer  prec,
bool  is_internal 
)
static

cut-and-pasted and adapted from multiply_to_transformer();

FI: I had to switch the arguments to satisfy a reasonnable assert in image_intersection(), but the switch may be detrimental to memory allocation.

The numerical value of expression e1 is known: v = lb1*v2

Definition at line 2169 of file expression.c.

2173 {
2174  type tv = entity_type(v);
2175  type t = type_undefined;
2176  if (type_variable_p(tv)) {
2178  if (basic_pointer_p(b))
2179  t = basic_pointer(b);
2180  }
2181  if (type_undefined_p(t)) {
2182  return transformer_empty();
2183  }
2184 
2185 
2186  // create an entity for sizeof(type)
2187  add_sizeof_value(t);
2188  // get the sizeof entity
2189  entity val2 = type_to_sizeof_value(t);
2190  // convert to expression for transformer
2191  expression e2 = entity_to_expression(val2);
2192 
2196  transformer t1 = safe_integer_expression_to_transformer(v1, e1, ipre, is_internal);
2198  transformer npre = transformer_safe_apply(t1, ipre);
2199  transformer t2 = safe_integer_expression_to_transformer(v2, e2, npre, is_internal);
2201  ipre;
2202 
2203  pips_debug(8, "Begin\n");
2204 
2206  int lb1 = 0;
2207  int ub1 = 0;
2208  //e2 sizeof then positive
2209 
2210  /* FI: I had to switch the arguments to satisfy a reasonnable
2211  assert in image_intersection(), but the switch may be
2212  detrimental to memory allocation. */
2213  //t1 = transformer_safe_image_intersection(pre, t1);
2214  t1 = transformer_normalize(t1, 2);
2215  t1 = transformer_range(transformer_apply(pre, t1));
2216 
2218 
2219  if(lb1==ub1) {
2220  /* The numerical value of expression e1 is known: v = lb1*v2 */
2221  Pvecteur veq = vect_new((Variable) v, VALUE_MONE);
2222 
2223  vect_add_elem(&veq, (Variable) v2, (Value) lb1);
2224  transformer_equality_add(t2, veq);
2225  tf = t2;
2226  free_transformer(t1);
2227  }
2228  else if(ub1<=0) { // e1 is negative
2229  // e2 is positive
2230  // v <= v1 * lb2, v <= ub1 * v2
2231  // v >= v1 * ub2, v >= lb1 * v2 (if lb1 and ub2 exist)
2232  tf = transformer_intersection(t1,t2); // FI: not good if side effects!
2233  tf = transformer_normalize(tf, 2);
2234  tf = transformer_add_inequality_with_linear_term(tf,v,v2,ub1,true);
2235  if(lb1>INT_MIN)
2236  tf = transformer_add_inequality_with_linear_term(tf,v,v2,lb1,false);
2237  }
2238  else if(lb1>=0) {
2239  // v >= lb1 * v2, v >= v1 * lb2
2240  // v <= ub1 * v2, v <= v1 * ub2 (if ub1 and ub2 exist)
2241  tf = transformer_intersection(t1,t2); // FI: not good if side effects!
2242  tf = transformer_normalize(tf, 2);
2243  tf = transformer_add_inequality_with_linear_term(tf,v,v2,lb1,false);
2244  if(ub1<INT_MAX)
2245  tf = transformer_add_inequality_with_linear_term(tf,v,v2,ub1,true);
2246  }
2247  else { // FI: This should now be obsolete...
2248  if(lb1>INT_MIN && ub1<INT_MAX) { // FI: separated test needed
2249  // v1 * lb2 <= v <= v1 * ub2
2250  tf = transformer_intersection(t1,t2); // FI: not good if side effects!
2251  tf = transformer_normalize(tf, 2);
2252  tf = transformer_add_inequality_with_linear_term(tf,v,v2,lb1,false);
2253  tf = transformer_add_inequality_with_linear_term(tf,v,v2,ub1,true);
2254  }
2255  else {
2256  long long lb = lb1;
2257  long long ub = ub1;
2258 
2259  free_transformer(t1);
2260  free_transformer(t2);
2261 
2262  if(lb > INT_MIN || ub < INT_MAX)
2263  tf = transformer_identity();
2264 
2265  if(lb > INT_MIN) {
2266  Pvecteur vineql = vect_new((Variable) v, VALUE_MONE);
2267 
2268  vect_add_elem(&vineql, TCST, lb);
2270  }
2271  if(ub < INT_MAX) {
2272  Pvecteur vinequ = vect_new((Variable) v, VALUE_ONE);
2273 
2274  vect_add_elem(&vinequ, TCST, -ub);
2275  tf = transformer_inequality_add(tf, vinequ);
2276  }
2277  }
2278  }
2279  }
2280  else if(!transformer_undefined_p(t1)) {
2281  free_transformer(t1);
2282  }
2283  else if(!transformer_undefined_p(t2)) {
2284  free_transformer(t2);
2285  }
2286 
2287  free_transformer(pre);
2288  free_expression(e2);
2289 
2290  pips_debug(8, "End with tf=%p\n", tf);
2291  ifdebug(8) (void) dump_transformer(tf);
2292 
2293  return tf;
2294 }
void free_expression(expression p)
Definition: ri.c:853
transformer transformer_add_inequality_with_linear_term(transformer tf, entity v, entity x, int a, bool less_than_p)
Add the inequality v <= a x or v >= a x.
Definition: basic.c:530
transformer transformer_empty()
Allocate an empty transformer.
Definition: basic.c:120
#define basic_pointer(x)
Definition: ri.h:637
#define type_undefined_p(x)
Definition: ri.h:2884
#define type_undefined
Definition: ri.h:2883
transformer safe_integer_expression_to_transformer(entity v, expression expr, transformer pre, bool is_internal)
Always return a defined transformer, using effects in case a more precise analysis fails.
Definition: expression.c:3552
void integer_expression_and_precondition_to_integer_interval(expression, transformer, int *, int *)
Could be used for bool expressions too? Extended to any kind of expression?
Definition: utils.c:386
transformer transformer_safe_apply(transformer tf, transformer pre)
Definition: transformer.c:1627
void add_sizeof_value(type)
For a given architecture, sizeof(t) is a constant.
Definition: value.c:1352
entity type_to_sizeof_value(type)
Definition: value.c:899

References add_sizeof_value(), basic_pointer, basic_pointer_p, dump_transformer, entity_to_expression(), entity_type, free_expression(), free_transformer(), ifdebug, integer_expression_and_precondition_to_integer_interval(), make_local_temporary_value_entity(), pips_debug, safe_integer_expression_to_transformer(), TCST, transformer_add_inequality_with_linear_term(), transformer_apply(), transformer_empty(), transformer_equality_add(), transformer_identity(), transformer_inequality_add(), transformer_intersection(), transformer_normalize(), transformer_range(), transformer_safe_apply(), transformer_undefined, transformer_undefined_p, type_to_sizeof_value(), type_undefined, type_undefined_p, type_variable, type_variable_p, VALUE_MONE, VALUE_ONE, variable_basic, vect_add_elem(), and vect_new().

Referenced by pointer_binary_operation_to_transformer(), pointer_call_expression_to_transformer(), and pointer_expression_to_transformer().

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

◆ expression_to_points_to_sinks()

◆ expression_to_points_to_sources()

◆ expression_to_transformer()

transformer expression_to_transformer ( expression  exp,
transformer  pre,
list  el 
)

Just to capture side effects as the returned value is ignored.

Example: "(void) inc(&i);".

Or to capture the return of a struct, which cannot be expressed with an atomic return value.

FI: I assume this implies a cast to (void) but I'm wrong for any call to a void function.

FI: I do not remember the meaning of the last parameter

Must be a call to a void function

Wait till it happpens...

FI: is_internal_p has an impact on renaming in simple_affine_to_transformer().

FI: there may be (many) other exceptions with intrinsics...

Fortran intrinsics, such as IOs, are not taken into account because these code should not be executed for Fortran code.

If everything else has failed.

Parameters
expxp
prere
ell

Definition at line 5190 of file expression.c.

5194 {
5196  //entity tmpv = entity_undefined;
5198 
5199  if(type_void_p(et)) {
5200  /* FI: I assume this implies a cast to (void) but I'm wrong for
5201  any call to a void function. */
5202  syntax s_exp = expression_syntax(exp);
5203 
5204  if(syntax_cast_p(s_exp)) {
5205  expression sub_exp = cast_expression(syntax_cast(s_exp));
5206  type cet = expression_to_type(sub_exp);
5207 
5208  if(analyzed_type_p(cet)) {
5210 
5211  /* FI: I do not remember the meaning of the last parameter */
5212  // it's use in generic_reference_to_transformer
5213  tf = any_expression_to_transformer(tmpv, sub_exp, pre, false);
5214  }
5215  free_type(cet);
5216  }
5217  else if(syntax_call_p(s_exp)) {
5218  /* Must be a call to a void function */
5219  call c = syntax_call(s_exp);
5220  //list el = expression_to_proper_effects(exp);;
5222  tf = call_to_transformer(c, pre, el);
5223  }
5224  else {
5225  /* Wait till it happpens... */
5226  pips_internal_error("This case is not handled yet");
5227  }
5228  }
5229  else if(analyzed_type_p(et)) {
5231  /* FI: is_internal_p has an impact on renaming in
5232  simple_affine_to_transformer(). */
5233  tf = any_expression_to_transformer(tmpv, exp, pre, true);
5234  }
5235  else {
5236  // FI: we should go down recursively anyway because of casts and
5237  // side effects in C...
5241  }
5242  else if(expression_call_p(exp)) {
5243  call c = expression_call(exp);
5244  entity f = call_function(c);
5245  /* FI: there may be (many) other exceptions with intrinsics...
5246  *
5247  * Fortran intrinsics, such as IOs, are not taken into account
5248  * because these code should not be executed for Fortran code.
5249  */
5252  pre);
5253  }
5254  else if (entity_module_p(f)){
5255  list al = call_arguments(c);
5256  tf = user_call_to_transformer(f, al, pre, el);
5257  }
5258  else
5259  // FI: I am not pleased with this at all, but no time to think
5261  }
5262  else if(expression_cast_p(exp)) {
5263  cast c = expression_cast(exp);
5264  expression sub_exp = cast_expression(c);
5265  tf = safe_expression_to_transformer(sub_exp, pre);
5266  }
5270  expression sub_exp = sizeofexpression_expression(soe);
5271  tf = safe_expression_to_transformer(sub_exp, pre);
5272  }
5273  }
5274  else if(expression_subscript_p(exp)) {
5278  transformer tf2
5280  tf = transformer_combine(tf1, tf2);
5281  free_transformer(tf2); // tf1 is exported in tf
5282  }
5283  else if(expression_application_p(exp)) {
5285  expression func = application_function(a);
5287  transformer tf2
5289  tf = transformer_combine(tf1, tf2);
5290  free_transformer(tf2); // tf1 is exported in tf
5291  }
5292  // FI: Many other possible cases: range, sizeofexpression, subscript,
5293  // application, va_arg
5294  }
5295 
5296  /* If everything else has failed. */
5297  if(transformer_undefined_p(tf))
5298  tf = effects_to_transformer(el);
5299  else
5301 
5302  free_type(et);
5303 
5304  return tf;
5305 }
void free_type(type p)
Definition: ri.c:2658
bdt base
Current expression.
Definition: bdt_read_paf.c:100
#define ENTITY_POINT_TO_P(e)
#define ENTITY_FIELD_P(e)
C data structure and pointer management.
bool entity_module_p(entity e)
Definition: entity.c:683
subscript expression_subscript(expression e)
Definition: expression.c:1843
bool expression_sizeofexpression_p(expression e)
Definition: expression.c:460
application expression_application(expression e)
Definition: expression.c:485
bool expression_subscript_p(expression e)
Definition: expression.c:1838
bool expression_application_p(expression e)
Duplicate bool expression_subscript_p(expression e) { return(syntax_subscript_p(expression_syntax(e))...
Definition: expression.c:480
sizeofexpression expression_sizeofexpression(expression e)
Definition: expression.c:465
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
type expression_to_type(expression)
For an array declared as int a[10][20], the type returned for a[i] is int [20].
Definition: type.c:2486
type compute_basic_concrete_type(type)
computes a new type which is the basic concrete type of the input type (this new type is not stored i...
Definition: type.c:3556
#define type_void_p(x)
Definition: ri.h:2959
#define syntax_cast_p(x)
Definition: ri.h:2737
transformer user_call_to_transformer(entity f, list pc, transformer pre, list ef)
transformer call_to_transformer(call c, transformer pre, list ef)
Use to be static, but may be called from expressions in C.
transformer generic_reference_to_transformer(entity v, reference r, transformer pre, bool is_internal)
TYPE INDEPENDENT OPERATIONS.
Definition: expression.c:126
bool analyzed_type_p(type)
The type t is one of the analyzed types.
Definition: value.c:367

References analyzed_type_p(), any_expression_to_transformer(), application_arguments, application_function, base, call_arguments, call_function, call_to_transformer(), CAR, cast_expression, compute_basic_concrete_type(), effects_to_transformer(), ENTITY_FIELD_P, entity_module_p(), ENTITY_POINT_TO_P, entity_undefined, exp, EXPRESSION, expression_application(), expression_application_p(), expression_call(), expression_call_p(), expression_cast(), expression_cast_p(), expression_reference(), expression_reference_p(), expression_sizeofexpression(), expression_sizeofexpression_p(), expression_subscript(), expression_subscript_p(), expression_syntax, expression_to_proper_constant_path_effects(), expression_to_type(), expressions_to_transformer(), f(), free_transformer(), free_type(), generic_reference_to_transformer(), make_local_temporary_value_entity(), pips_internal_error, safe_expression_to_transformer(), sizeofexpression_expression, sizeofexpression_expression_p, subscript_array, subscript_indices, syntax_call, syntax_call_p, syntax_cast, syntax_cast_p, transformer_combine(), transformer_temporary_value_projection(), transformer_undefined, transformer_undefined_p, type_void_p, and user_call_to_transformer().

Referenced by expression_to_postcondition(), instruction_to_transformer(), and safe_expression_to_transformer().

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

◆ expressions_to_transformer()

transformer expressions_to_transformer ( list  expl,
transformer  pre 
)

Compute the transformer associated to a list of expressions such as "i=0, j = 1;".

The value returned is ignored.

el is an over-appoximation; should be replaced by a safe_expression_to_transformer() taking care of computing the precise effects of exp instead of using the effects of expl.

Parameters
explxpl
prere

Definition at line 5722 of file expression.c.

5724 {
5728 
5729  FOREACH(EXPRESSION, exp, expl) {
5730  /* el is an over-appoximation; should be replaced by a
5731  safe_expression_to_transformer() taking care of computing the
5732  precise effects of exp instead of using the effects of expl. */
5733  transformer cpre_r = transformer_range(cpre);
5736 
5737  tf = transformer_combine(tf, ctf);
5738  tf = transformer_normalize(tf, 2);
5739  npre = transformer_apply(ctf, cpre);
5740  npre = transformer_normalize(npre, 2);
5741  free_transformer(cpre);
5742  free_transformer(cpre_r);
5743  cpre = npre;
5744  }
5745  free_transformer(cpre);
5746  return tf;
5747 }

References copy_transformer(), exp, EXPRESSION, FOREACH, free_transformer(), safe_expression_to_transformer(), transformer_apply(), transformer_combine(), transformer_identity(), transformer_normalize(), transformer_range(), transformer_undefined, and transformer_undefined_p.

Referenced by any_expression_side_effects_to_transformer(), any_expression_to_transformer(), expression_to_transformer(), generic_reference_to_transformer(), intrinsic_to_transformer(), and intrinsic_to_transformer_list().

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

◆ false_condition_wrt_precondition_p()

bool false_condition_wrt_precondition_p ( expression  c,
transformer  pre 
)
Parameters
prere

Definition at line 5891 of file expression.c.

5892 {
5893  bool result = false;
5894 
5895  result = eval_condition_wrt_precondition_p(c, pre, false);
5896 
5897  return result;
5898 }
bool eval_condition_wrt_precondition_p(expression c, transformer pre, bool veracity)
Definition: expression.c:5909

References eval_condition_wrt_precondition_p().

Referenced by whileloop_to_postcondition(), and whileloop_to_total_precondition().

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

◆ float_binary_operation_to_transformer()

static transformer float_binary_operation_to_transformer ( entity  e,
entity  op,
expression  e1,
expression  e2,
transformer  pre,
bool  is_internal 
)
static

Definition at line 4074 of file expression.c.

4081 {
4083 
4084  if(ENTITY_PLUS_P(op) || ENTITY_MINUS_P(op)) {
4085  tf = addition_operation_to_transformer(e, e1, e2, pre, ENTITY_PLUS_P(op), is_internal);
4086  }
4087  else if(ENTITY_ASSIGN_P(op)) {
4088  tf = assign_operation_to_transformer(e, e1, e2, pre);
4089  }
4090 
4091  return tf;
4092 }
#define ENTITY_ASSIGN_P(e)
#define ENTITY_MINUS_P(e)
#define ENTITY_PLUS_P(e)
static transformer addition_operation_to_transformer(entity v, expression e1, expression e2, transformer pre, bool addition_p, bool is_internal)
Type independent.
Definition: expression.c:438
transformer assign_operation_to_transformer(entity val, expression lhs, expression rhs, transformer pre)
Returns an undefined transformer in case of failure.
Definition: expression.c:2737

References addition_operation_to_transformer(), assign_operation_to_transformer(), ENTITY_ASSIGN_P, ENTITY_MINUS_P, ENTITY_PLUS_P, and transformer_undefined.

Referenced by float_call_expression_to_transformer().

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

◆ float_call_expression_to_transformer()

static transformer float_call_expression_to_transformer ( entity  v,
expression  expr,
transformer  pre,
bool  is_internal 
)
static

Just in case some integer variables were modified by the function call, e.g. the count of its dynamic calls.

tf = constant_to_transformer(v, call_function(syntax_call(srhs)));

min, max,...

Parameters
preneeded to compute effects for user calls

Definition at line 4095 of file expression.c.

4100 {
4101  syntax sexpr = expression_syntax(expr);
4102  call c = syntax_call(sexpr);
4103  entity op = call_function(c);
4104  list args = call_arguments(c);
4106  int arity = gen_length(args);
4107 
4108  if(ENTITY_AMIN1_P(op)||ENTITY_DMIN1_P(op)||ENTITY_MIN_P(op)) {
4109  tf = generic_minmax_to_transformer(v, args, pre, true, is_internal);
4110  }
4111  if(ENTITY_C_MIN_P(op)) {
4112  args=CDR(args);
4113  --arity;
4114  tf = generic_minmax_to_transformer(v, args, pre, true, is_internal);
4115  }
4116  else if(ENTITY_AMAX1_P(op)||ENTITY_DMAX1_P(op)||ENTITY_MAX_P(op)) {
4117  tf = generic_minmax_to_transformer(v, args, pre, false, is_internal);
4118  }
4119  else if(value_code_p(entity_initial(op))
4121  /* Just in case some integer variables were modified by the function
4122  call, e.g. the count of its dynamic calls. */
4123  tf = user_function_call_to_transformer(v, expr, pre);
4124  }
4125  else {
4126  switch(arity) {
4127  case 0:
4128  /* tf = constant_to_transformer(v, call_function(syntax_call(srhs))); */
4129  tf = constant_to_transformer(v, expr);
4130  break;
4131  case 1:
4132  {
4133  expression e1 = EXPRESSION(CAR(args));
4134  tf = float_unary_operation_to_transformer(v, op, e1, pre, is_internal);
4135  break;
4136  }
4137  case 2:
4138  {
4139  expression e1 = EXPRESSION(CAR(args));
4140  expression e2 = EXPRESSION(CAR(CDR(args)));
4141  tf = float_binary_operation_to_transformer(v, op, e1, e2, pre, is_internal);
4142  break;
4143  }
4144  default:
4145  /* min, max,... */
4146  semantics_user_warning("Operator %s not analyzed\n", entity_name(op));
4147  }
4148  }
4149 
4150  return tf;
4151 }
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
size_t gen_length(const list l)
Definition: list.c:150
#define SEMANTICS_INTERPROCEDURAL
#define ENTITY_DMAX1_P(e)
#define ENTITY_AMIN1_P(e)
#define ENTITY_C_MIN_P(e)
#define ENTITY_MAX_P(e)
#define ENTITY_AMAX1_P(e)
#define ENTITY_MIN_P(e)
#define ENTITY_DMIN1_P(e)
#define value_code_p(x)
Definition: ri.h:3065
#define entity_name(x)
Definition: ri.h:2790
#define entity_initial(x)
Definition: ri.h:2796
transformer user_function_call_to_transformer(entity e, expression expr, transformer pre)
a function call is a call to a non void function in C and to a FUNCTION in Fortran
static transformer float_binary_operation_to_transformer(entity e, entity op, expression e1, expression e2, transformer pre, bool is_internal)
Definition: expression.c:4074
static transformer generic_minmax_to_transformer(entity e, list args, transformer pre, bool minmax, bool is_internal)
Definition: expression.c:214
static transformer float_unary_operation_to_transformer(entity e, entity op, expression e1, transformer pre, bool is_internal)
Definition: expression.c:4054
static transformer constant_to_transformer(entity v, expression rhs)
Definition: expression.c:645

References call_arguments, call_function, CAR, CDR, constant_to_transformer(), ENTITY_AMAX1_P, ENTITY_AMIN1_P, ENTITY_C_MIN_P, ENTITY_DMAX1_P, ENTITY_DMIN1_P, entity_initial, ENTITY_MAX_P, ENTITY_MIN_P, entity_name, EXPRESSION, expression_syntax, float_binary_operation_to_transformer(), float_unary_operation_to_transformer(), gen_length(), generic_minmax_to_transformer(), get_bool_property(), SEMANTICS_INTERPROCEDURAL, semantics_user_warning, syntax_call, transformer_undefined, user_function_call_to_transformer(), and value_code_p.

Referenced by float_expression_to_transformer().

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

◆ float_expression_to_transformer()

transformer float_expression_to_transformer ( entity  v,
expression  rhs,
transformer  pre,
bool  is_internal 
)

pre can be used if some integer variables with constant values have to be promoted to float.

pips_assert("Precondition is undefined", transformer_undefined_p(pre));

Parameters
rhshs
prere
is_internals_internal

Definition at line 4153 of file expression.c.

4157 {
4159  syntax srhs = expression_syntax(rhs);
4160 
4161  /* pre can be used if some integer variables with constant values have
4162  to be promoted to float. */
4163 
4164  /* pips_assert("Precondition is undefined", transformer_undefined_p(pre)); */
4165 
4166  switch(syntax_tag(srhs)) {
4167  case is_syntax_call:
4168  tf = float_call_expression_to_transformer(v, rhs, pre, is_internal);
4169  break;
4170  case is_syntax_reference:
4171  {
4172  //entity e = reference_variable(syntax_reference(srhs));
4173  // FI: some filtering needed if integer expressions should not
4174  // be exploited...
4175  reference r = syntax_reference(srhs);
4176  tf = generic_reference_to_transformer(v, r, pre, is_internal);
4177  break;
4178  }
4179  case is_syntax_range:
4180  pips_internal_error("Unexpected tag %d", syntax_tag(srhs));
4181  break;
4182  default:
4183  pips_internal_error("Illegal tag %d", syntax_tag(srhs));
4184  }
4185 
4186  return tf;
4187 }
static transformer float_call_expression_to_transformer(entity v, expression expr, transformer pre, bool is_internal)
Definition: expression.c:4095

References expression_syntax, float_call_expression_to_transformer(), generic_reference_to_transformer(), is_syntax_call, is_syntax_range, is_syntax_reference, pips_internal_error, syntax_reference, syntax_tag, and transformer_undefined.

Referenced by any_expression_to_transformer().

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

◆ float_unary_operation_to_transformer()

static transformer float_unary_operation_to_transformer ( entity  e,
entity  op,
expression  e1,
transformer  pre,
bool  is_internal 
)
static

Definition at line 4054 of file expression.c.

4060 {
4062 
4063  tf = generic_unary_operation_to_transformer(e, op, e1, pre, is_internal);
4064 
4065  if(transformer_undefined_p(tf)) {
4066  // tf = points_to_unary_operation_to_transformer(e, op, e1, pre, is_internal, false);
4067  tf = generic_unary_operation_to_transformer(e, op, e1, pre, is_internal);
4068  }
4069 
4070  return tf;
4071 }
static transformer generic_unary_operation_to_transformer(entity e, entity op, expression e1, transformer pre, bool is_internal)
Definition: expression.c:356

References generic_unary_operation_to_transformer(), transformer_undefined, and transformer_undefined_p.

Referenced by float_call_expression_to_transformer().

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

◆ generic_abs_to_transformer()

static transformer generic_abs_to_transformer ( entity  v,
expression  expr,
transformer  pre,
bool  is_internal 
)
static

forward declaration

Copy of iabs_to_transformer(), which is probably never called anymore.

Expression expr may be of a type different from v's type because abs maybe generic and because type conversions may be implicit

Parameters
exprassumed to be a value

Definition at line 1725 of file expression.c.

1729 {
1731  /* Expression expr may be of a type different from v's type because
1732  abs maybe generic and because type conversions may be implicit */
1734  type et = expression_to_type(expr);
1735  transformer etf = any_expression_to_transformer(tv, expr, pre, is_internal);
1736  int lb=INT_MIN, ub=INT_MAX;
1737 
1738  pips_debug(8, "begin\n");
1739 
1740  if(integer_type_p(et))
1742  free_type(et);
1743 
1744  if(ub==lb) {
1746  }
1747  else if(lb>=0) {
1748  tf = transformer_add_equality(tf, v, tv);
1749  }
1750  else if(ub<=0) {
1753  }
1754  else {
1755  Pvecteur vlb1 = vect_new((Variable) tv, VALUE_ONE);
1756  Pvecteur vlb2 = vect_new((Variable) tv, VALUE_MONE);
1757 
1758 
1759  vect_add_elem(&vlb1, (Variable) v, VALUE_MONE);
1760  vect_add_elem(&vlb2, (Variable) v, VALUE_MONE);
1761 
1762  tf = transformer_inequality_add(tf, vlb1);
1763  tf = transformer_inequality_add(tf, vlb2);
1764  }
1765 
1767  free_transformer(etf);
1768 
1769  ifdebug(8) {
1770  pips_debug(8, "result:\n");
1771  dump_transformer(tf);
1772  pips_debug(8, "end\n");
1773  }
1774 
1775  return tf;
1776 }
#define VALUE_ZERO
transformer transformer_add_equality_with_affine_term(transformer tf, entity v, entity x, int a, int cst)
Add the equality v = a x + cst.
Definition: basic.c:517
bool integer_type_p(type)
Definition: type.c:3298
#define abs(v)
Definition: syntax-local.h:48

References abs, any_expression_to_transformer(), dump_transformer, entity_type, expression_to_type(), free_transformer(), free_type(), ifdebug, integer_expression_and_precondition_to_integer_interval(), integer_type_p(), make_local_temporary_value_entity(), pips_debug, transformer_add_equality(), transformer_add_equality_with_affine_term(), transformer_add_equality_with_integer_constant(), transformer_identity(), transformer_inequality_add(), transformer_safe_image_intersection(), VALUE_MONE, VALUE_ONE, VALUE_ZERO, vect_add_elem(), and vect_new().

Referenced by generic_unary_operation_to_transformer().

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

◆ generic_minmax_to_transformer()

static transformer generic_minmax_to_transformer ( entity  e,
list  args,
transformer  pre,
bool  minmax,
bool  is_internal 
)
static

pips_assert("Precondition is unused", transformer_undefined_p(pre));

memory leak!

A miracle occurs and the proper basis is derived from the constraints ( I do not understand why the new and the old value of e both appear... so it may not be necessary for the consistency check... I'm lost, FI, 6 Jan. 1999)

cl could be kept but would be always projected later

Definition at line 214 of file expression.c.

219 {
222  list cexpr;
224 
225  pips_debug(8, "begin\n");
226 
227  pips_assert("At least one argument", gen_length(args)>=1);
228 
229  /* pips_assert("Precondition is unused", transformer_undefined_p(pre)); */
230 
231  for(cexpr = args; !ENDP(cexpr); POP(cexpr)) {
232  expression arg = EXPRESSION(CAR(cexpr));
233  type t = entity_type(e);
235  transformer tfe = any_expression_to_transformer(tmp, arg, pre, is_internal);
236 
237  Pvecteur v = vect_new((Variable) tmp, VALUE_ONE);
239 
241 
242  if(minmax) {
243  v = vect_multiply(v, VALUE_MONE);
244  }
245 
246  cv = contrainte_make(v);
247  cv->succ = cl;
248  cl = cv;
249 
250  /* memory leak! */
251  tf_acc = transformer_safe_image_intersection(tf_acc, tfe);
252  }
253 
254 
257 
258  sc_base(sc) = base_add_variable(BASE_NULLE, (Variable) e);
259  sc_dimension(sc) = 1;
260  tf = make_transformer(NIL,
261  make_predicate(sc));
262  }
263  else {
264  /* A miracle occurs and the proper basis is derived from the
265  constraints ( I do not understand why the new and the old value
266  of e both appear... so it may not be necessary for the
267  consistency check... I'm lost, FI, 6 Jan. 1999) */
268  if(!transformer_undefined_p(tf_acc)) {
269  tf_acc = transformer_inequalities_add(tf_acc, cl);
270  }
271  else {
272  /* cl could be kept but would be always projected later */
273  contraintes_free(cl);
274  }
275  tf = tf_acc;
276  }
277 
278  ifdebug(8) {
279  pips_debug(8, "result:\n");
280  dump_transformer(tf);
281  pips_debug(8, "end\n");
282  }
283 
284  return tf;
285 }
Pbase base_add_variable(Pbase b, Variable var)
Pbase base_add_variable(Pbase b, Variable v): add variable v as a new dimension to basis b at the end...
Definition: base.c:88
transformer transformer_inequalities_add(transformer tf, Pcontrainte ineqs)
Warning:
Definition: basic.c:409
#define CONTRAINTE_UNDEFINED_P(c)
#define CONTRAINTE_NULLE_P(c)
contrainte nulle (non contrainte 0 == 0 ou 0 <= 0)
Pcontrainte contraintes_free(Pcontrainte pc)
Pcontrainte contraintes_free(Pcontrainte pc): desallocation de toutes les contraintes de la liste pc.
Definition: alloc.c:226
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
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
struct Scontrainte * succ
#define BASE_NULLE
MACROS SUR LES BASES.

References any_expression_to_transformer(), base_add_variable(), BASE_NULLE, CAR, contrainte_make(), CONTRAINTE_NULLE_P, CONTRAINTE_UNDEFINED, CONTRAINTE_UNDEFINED_P, contraintes_free(), dump_transformer, ENDP, entity_type, EXPRESSION, gen_length(), ifdebug, make_local_temporary_value_entity(), make_predicate(), make_transformer(), NIL, pips_assert, pips_debug, POP, sc_make(), Scontrainte::succ, transformer_inequalities_add(), transformer_safe_image_intersection(), transformer_undefined, transformer_undefined_p, VALUE_MONE, VALUE_ONE, vect_add_elem(), vect_multiply(), and vect_new().

Referenced by float_call_expression_to_transformer().

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

◆ generic_reference_to_transformer()

transformer generic_reference_to_transformer ( entity  v,
reference  r,
transformer  pre,
bool  is_internal 
)

TYPE INDEPENDENT OPERATIONS.

expression.c

May return an undefined transformer

If you are dealing with a C array reference, find transformers for each subscript expression in case of side effects.

Parameters
prere
is_internals_internal

Definition at line 126 of file expression.c.

130 {
132  entity rv = reference_variable(r);
133  list sl = reference_indices(r);
134 
135  //FI: we could do better if the subscripts are constants
136  // we could try to use constant_memory_access_path_to_location_entity()
137  // after checking that the reference is constant
138 
139  if(ENDP(sl) && ((!is_internal && analyzable_scalar_entity_p(rv))
140  || entity_has_values_p(rv))) {
141  if(!entity_undefined_p(v)) {
142  entity rv_new = is_internal?
144  transformer tfr = simple_equality_to_transformer(v, rv_new, false);
145  if(!transformer_undefined_p(pre)) {
146  // FI: assume pre is a range
147  tf = transformer_intersection(tfr, pre);
148  }
149  free_transformer(tfr);
150  }
151  }
152  else if(ENDP(sl)) {
153  // Might be a constant value for a pointer, such as "a", an array
155  if(array_type_p(t)) {
156  // int d = (int) gen_length(variable_indices(type_variable(t)));
157  // list sl = make_zero_subscripts(d);
159  reference r = make_reference(rv, sl);
160  entity l = constant_memory_access_path_to_location_entity(r); // l is a constant location
161  if(!entity_undefined_p(l)) {
162  transformer tfr = simple_equality_to_transformer(v, l, false);
163  if(!transformer_undefined_p(pre)) {
164  // FI: assume pre is a range
165  tf = transformer_intersection(tfr, pre);
166  }
167  free_transformer(tfr);
168  }
169  }
170  }
171  else if(get_bool_property("SEMANTICS_ANALYZE_CONSTANT_PATH")) {
173  // an array reference may have an impact on some values
175  if(analyzed_type_p(t)) {
176  bool processed_p = false;
179  if(!entity_undefined_p(rv) && !entity_undefined_p(v)) {
180  processed_p = true;
181  tf = transformer_add_equality(tf, v, rv);
182  }
183  }
184  if(!processed_p) {
185  // FI: not sure why we would only be interested in modified variables
187  FOREACH(ENTITY, wv, wvl) {
188  if(location_entity_p(wv)) {
189  value val = entity_initial(wv);
190  reference lr = value_reference(val);
191  // FI: when a precondition is available, it should be used
192  // to build almost a dependence test
193  if(references_may_conflict_p(r, lr)) {
194  tf = transformer_add_variable_update(tf, wv);
195  }
196  }
197  }
198  }
199  }
200  }
201 
202  if(transformer_undefined_p(tf)) {
203  /* If you are dealing with a C array reference, find transformers
204  for each subscript expression in case of side effects. */
206  if(c_language_module_p(m)) {
208  }
209  }
210  return tf;
211 }
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
transformer transformer_add_variable_update(transformer t, entity v)
Add an update of variable v into t.
Definition: basic.c:289
bool location_entity_p(entity)
Definition: locations.c:349
type points_to_reference_to_concrete_type(reference)
Definition: type.c:685
entity constant_memory_access_path_to_location_entity(reference)
A constant memory access path may not be considered.
Definition: locations.c:329
bool references_may_conflict_p(reference r1, reference r2)
Check if two references may conflict.
Definition: conflicts.c:426
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
expression make_zero_expression(void)
Make a zero expression.
Definition: expression.c:1212
bool store_independent_reference_p(reference r)
Does this reference define the same set of memory locations regardless of the current (environment an...
Definition: expression.c:3108
bool c_language_module_p(entity m)
Definition: module.c:447
bool array_type_p(type)
Definition: type.c:2942
type entity_basic_concrete_type(entity)
retrieves or computes and then returns the basic concrete type of an entity
Definition: type.c:3677
#define value_reference(x)
Definition: ri.h:3085
#define entity_undefined_p(x)
Definition: ri.h:2762
bool analyzable_scalar_entity_p(entity)
The entity type is one of the analyzed types.
Definition: value.c:471
entity external_entity_to_new_value(entity)
Definition: value.c:1411
list modified_variables_with_values(void)
Return the list of all analyzed variables which are modified in the current module.
Definition: value.c:1094

References analyzable_scalar_entity_p(), analyzed_type_p(), array_type_p(), c_language_module_p(), CONS, constant_memory_access_path_to_location_entity(), ENDP, ENTITY, entity_basic_concrete_type(), entity_has_values_p(), entity_initial, entity_to_new_value(), entity_undefined_p, EXPRESSION, expressions_to_transformer(), external_entity_to_new_value(), FOREACH, free_transformer(), get_bool_property(), get_current_module_entity(), location_entity_p(), make_reference(), make_zero_expression(), modified_variables_with_values(), NIL, points_to_reference_to_concrete_type(), reference_indices, reference_variable, references_may_conflict_p(), simple_equality_to_transformer(), store_independent_reference_p(), transformer_add_equality(), transformer_add_variable_update(), transformer_intersection(), transformer_undefined, transformer_undefined_p, and value_reference.

Referenced by assign_rhs_to_reflhs_to_transformer(), expression_to_transformer(), float_expression_to_transformer(), integer_expression_to_transformer(), pointer_expression_to_transformer(), and points_to_unary_operation_to_transformer().

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

◆ generic_unary_operation_to_transformer()

static transformer generic_unary_operation_to_transformer ( entity  e,
entity  op,
expression  e1,
transformer  pre,
bool  is_internal 
)
static

FI: Oops, the precondition is lost here! See any_basic_update_to_transformer()

And loop over the possible source locations

A very similar loop is used in lhs_expression_to_transformer() and in struct_refrence_assignment_to_transformer()...

Definition at line 356 of file expression.c.

362 {
364 
365  if(ENTITY_UNARY_MINUS_P(op)) {
366  tf = unary_minus_operation_to_transformer(e, e1, pre, is_internal);
367  }
368  else if(ENTITY_IABS_P(op) || ENTITY_ABS_P(op) || ENTITY_DABS_P(op)
369  || ENTITY_CABS_P(op)
370  || ENTITY_C_ABS_P(op) || ENTITY_LABS_P(op) || ENTITY_LLABS_P(op)
371  || ENTITY_IMAXABS_P(op)
372  || ENTITY_FABS_P(op) || ENTITY_FABSF_P(op) || ENTITY_FABSL_P(op)
373  || ENTITY_C_CABS_P(op) || ENTITY_CABSF_P(op) || ENTITY_CABSL_P(op)) {
374  tf = generic_abs_to_transformer(e, e1, pre, is_internal);
375  }
380 
381  if(entity_has_values_p(v1)) {
383  if(transformer_undefined_p(pre)) {
384  tf = tfu;
385  }
386  else {
387  /* FI: Oops, the precondition is lost here! See any_basic_update_to_transformer() */
388  tf = transformer_combine(transformer_range(pre), tfu);
389  free_transformer(tfu);
390  }
391  }
392  }
393  else if(ENTITY_DEREFERENCING_P(op)) {
395  int n = (int) gen_length(ll);
396 
397  /* And loop over the possible source locations
398  *
399  * A very similar loop is used in lhs_expression_to_transformer()
400  * and in struct_refrence_assignment_to_transformer()...
401  */
403  FOREACH(CELL, cp, ll) {
404  reference r = cell_any_reference(cp); // rhs location
405  // The preconditions may make the convex hull useful when
406  // different locations have known values or are
407  // constrained...
408  transformer rt = copy_transformer(pre);
409 
412  if(!entity_undefined_p(l)) {
413  rt = transformer_add_equality(rt, e, l);
414  }
415  }
416  else {
417  free_transformer(rt);
419  }
420 
421  if (transformer_undefined_p(ntf))
422  ntf = rt;
423  else {
424  if(!transformer_undefined_p(rt)) {
425  ntf = transformer_convex_hull(ntf, rt);
426  free_transformer(rt);
427  }
428  }
429  }
430  tf = ntf;
431  }
432 
433  return tf;
434 }
void const char const char const int
reference cell_any_reference(cell)
API for reference.
Definition: effects.c:77
#define CELL(x)
CELL.
Definition: effects.h:424
#define ENTITY_DABS_P(e)
#define ENTITY_FABSL_P(e)
#define ENTITY_UNARY_MINUS_P(e)
#define ENTITY_DEREFERENCING_P(e)
#define ENTITY_CABSL_P(e)
#define ENTITY_FABS_P(e)
#define ENTITY_CABSF_P(e)
#define ENTITY_C_CABS_P(e)
#define ENTITY_PRE_DECREMENT_P(e)
#define ENTITY_IMAXABS_P(e)
#define ENTITY_CABS_P(e)
#define ENTITY_C_ABS_P(e)
#define ENTITY_LLABS_P(e)
#define ENTITY_IABS_P(e)
#define ENTITY_ABS_P(e)
#define ENTITY_LABS_P(e)
#define ENTITY_FABSF_P(e)
Pvecteur cp
pointeur sur l'egalite ou l'inegalite courante
Definition: sc_read.c:87
bool semantics_usable_points_to_reference_p(reference rlhs, expression lhs, int n)
See if references rlhs is usable and process null, undefined and anywhere locations defined by rlhs.
Definition: expression.c:6194
static transformer generic_abs_to_transformer(entity, expression, transformer, bool)
forward declaration
Definition: expression.c:1725
transformer any_basic_update_operation_to_transformer(entity tmp, entity v, entity op)
See also any_basic_update_to_transformer(), which should be based on this function.
Definition: expression.c:317
static transformer unary_minus_operation_to_transformer(entity v, expression e1, transformer pre, bool is_internal)
Type independent.
Definition: expression.c:288
list semantics_expression_to_points_to_sinks(expression e)
Returns a list of cells.
Definition: points_to.c:112
s1
Definition: set.c:247

References any_basic_update_operation_to_transformer(), CELL, cell_any_reference(), constant_memory_access_path_to_location_entity(), copy_transformer(), cp, ENTITY_ABS_P, ENTITY_C_ABS_P, ENTITY_C_CABS_P, ENTITY_CABS_P, ENTITY_CABSF_P, ENTITY_CABSL_P, ENTITY_DABS_P, ENTITY_DEREFERENCING_P, ENTITY_FABS_P, ENTITY_FABSF_P, ENTITY_FABSL_P, entity_has_values_p(), ENTITY_IABS_P, ENTITY_IMAXABS_P, ENTITY_LABS_P, ENTITY_LLABS_P, ENTITY_POST_DECREMENT_P, ENTITY_POST_INCREMENT_P, ENTITY_PRE_DECREMENT_P, ENTITY_PRE_INCREMENT_P, ENTITY_UNARY_MINUS_P, entity_undefined_p, expression_syntax, FOREACH, free_transformer(), gen_length(), generic_abs_to_transformer(), int, reference_variable, s1, semantics_expression_to_points_to_sinks(), semantics_usable_points_to_reference_p(), syntax_reference, transformer_add_equality(), transformer_combine(), transformer_convex_hull(), transformer_range(), transformer_undefined, transformer_undefined_p, and unary_minus_operation_to_transformer().

Referenced by float_unary_operation_to_transformer(), integer_unary_operation_to_transformer(), logical_unary_operation_to_transformer(), and pointer_unary_operation_to_transformer().

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

◆ get_points_to_graph_from_statement()

static points_to_graph get_points_to_graph_from_statement ( _UNUSED_ statement  st)
static

semantic analysis: processing of expressions, with or without preconditions.

Expressions in Fortran were assumed to be side effect free most of the time and transformers were assumed to be linked to statements only. This is not true in C, where many constructs have side effects: Consider for instance the following three statements

n++; j = k = 2; i = j, k = i;

which may also appear as conditions, initializations or incrementations in compound statements (while, for, if).

Most functions here may return transformer_undefined when no interesting polyhedral approximation exists because the problem was fixed later at the statement level by using effects. For C, we need new functions which always succeed. So we need effects at the expression level although they are not stored in the PIPS database.

Moreover, temporary values are used to combine subexpressions. These temporary values must be projected when a significant transformer has been obtained, but not earlier. The temporary value counter cannot be reset before all temporary variables have been projected (eliminated). So functions which are called recursively cannot project temporary values and reset the temporary value counter. We can use wrapping functions and/or an additional argument, is_internal, to know whether temporary variables should be eliminated or not when returning the transformer.

Note that since expressions have side effects, preconditions must be updated along the left-to-right expression abstraction process. For example:

j = 2; i = j + (j = 0) + j;

but such a case is forbidden by the C99 standard. The result of the evaluation of such an expression is undefined.

Definition at line 93 of file expression.c.

95 {
96  pips_internal_error("points-to library not available");
97  return NULL;
98 }

References pips_internal_error.

◆ have_null_value_in_pointer_expression_p()

static bool have_null_value_in_pointer_expression_p ( expression  expr)
static

POINTER EXPRESSION.

Maybe move in ri-util/expression.c or in effect-util/pointer_values.c

search in an arithmetic pointer expression if the pointer NULL is present

Parameters
exprarithmetic expression to scan
Returns
true if expr contain NULL else false

Definition at line 4198 of file expression.c.

4198  {
4199  syntax sexpr = expression_syntax(expr);
4200 
4201  switch (syntax_tag(sexpr)) {
4202  case is_syntax_reference:
4203  {
4204  reference rexpr = syntax_reference(sexpr);
4205  entity var = reference_variable(rexpr);
4206 
4208  basic b = variable_basic(type_variable(bctvar));
4209 
4210  if (basic_pointer_p(b)) {
4211  semantics_user_warning("TODO : Need to check if %s is indirectly NULL\n", expression_to_string(expr));
4212  // TODO : function that check if we have an expression/entity e=NULL in the transformer t
4213  // have to make projection of e and NULL (because can have : e=e1, e1=NULL)
4214  // is_entity/expression_equal_null_in_transformer(var/expr, pre)
4215  // Maybe we can use the info from points-to, we can want to analyze pointer without graph points-to, why?
4216  if (null_pointer_value_entity_p(var) || expression_null_p(expr)) //this test can be not sufficient
4217  return true;
4218  else
4219  return false;
4220  }
4221  else
4222  return false;
4223  break;
4224  }
4225  case is_syntax_call:
4226  {
4227  call cexpr = syntax_call(sexpr);
4228  entity func = call_function(cexpr);
4229 
4230  if (ENTITY_PLUS_P(func) || ENTITY_PLUS_C_P(func) ||
4231  ENTITY_MINUS_P(func) || ENTITY_MINUS_C_P(func)) {
4232  list args = call_arguments(cexpr);
4233  expression e1 = EXPRESSION(CAR(args));
4234  expression e2 = EXPRESSION(CAR(CDR(args)));
4235  pips_assert("2 args for arithmetic", CDR(CDR(args))==NIL);
4236 
4238  }
4239  else if (expression_constant_p(expr)) {
4240  return false;
4241  }
4242  else if(ENTITY_MULTIPLY_P(func)) {
4243  return false;
4244  }
4245  else {
4246  //this case normally never happen
4247  pips_internal_error("unexpected function call : %s\n", entity_name(func));
4248  }
4249  break;
4250  }
4251  default:
4252  //this case normally never happen
4253  pips_internal_error("unexpected syntaxe tag : %i\n", syntax_tag(sexpr));
4254  }
4255 
4256  //this case normally never happen
4257  pips_internal_error("error with expression : %s, syntax_tag : %i \n", expression_to_string(expr), syntax_tag(sexpr));
4258  return false;
4259 }
bool null_pointer_value_entity_p(entity)
#define ENTITY_MULTIPLY_P(e)
#define ENTITY_PLUS_C_P(e)
#define ENTITY_MINUS_C_P(e)
bool expression_constant_p(expression exp)
================================================================
Definition: expression.c:2453
bool expression_null_p(expression exp)
returns true if the expression is equal to zero or NULL (even if there is a cast before such as in (v...
Definition: expression.c:2611
static bool have_null_value_in_pointer_expression_p(expression expr)
POINTER EXPRESSION.
Definition: expression.c:4198

References basic_pointer_p, call_arguments, call_function, CAR, CDR, compute_basic_concrete_type(), ENTITY_MINUS_C_P, ENTITY_MINUS_P, ENTITY_MULTIPLY_P, entity_name, ENTITY_PLUS_C_P, ENTITY_PLUS_P, entity_type, EXPRESSION, expression_constant_p(), expression_null_p(), expression_syntax, expression_to_string(), is_syntax_call, is_syntax_reference, NIL, null_pointer_value_entity_p(), pips_assert, pips_internal_error, reference_variable, semantics_user_warning, syntax_call, syntax_reference, syntax_tag, type_variable, and variable_basic.

Referenced by pointer_binary_operation_to_transformer().

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

◆ have_sizeof_value_in_multiply_pointer_expression_p()

static bool have_sizeof_value_in_multiply_pointer_expression_p ( expression  expr)
static

Maybe move in ri-util/expression.c or in effect-util/pointer_values.c.

search in an arithmetic pointer expression if the pointer NULL is present

Parameters
exprarithmetic expression to scan
Returns
true if expr contain NULL else false

Definition at line 4268 of file expression.c.

4268  {
4269  syntax sexpr = expression_syntax(expr);
4270 
4271  switch (syntax_tag(sexpr)) {
4272  case is_syntax_reference:
4273  {
4274  reference rexpr = syntax_reference(sexpr);
4275  entity var = reference_variable(rexpr);
4276 
4277  if (sizeof_value_entity_p(var)) {
4278  return true;
4279  }
4280  else
4281  return false;
4282  break;
4283  }
4284  case is_syntax_call:
4285  {
4286  call cexpr = syntax_call(sexpr);
4287  entity func = call_function(cexpr);
4288 
4289  if (ENTITY_MULTIPLY_P(func)) {
4290  list args = call_arguments(cexpr);
4291  expression e1 = EXPRESSION(CAR(args));
4292  expression e2 = EXPRESSION(CAR(CDR(args)));
4293  pips_assert("2 args for arithmetic", CDR(CDR(args))==NIL);
4294 
4296  }
4297  break;
4298  }
4299  default:
4300  return false;
4301  }
4302 
4303  //this case normally never happen
4304  pips_internal_error("error with expression : %s, syntax_tag : %i \n", expression_to_string(expr), syntax_tag(sexpr));
4305  return false;
4306 }
static bool have_sizeof_value_in_multiply_pointer_expression_p(expression expr)
Maybe move in ri-util/expression.c or in effect-util/pointer_values.c.
Definition: expression.c:4268
bool sizeof_value_entity_p(entity)
Definition: value.c:969

References call_arguments, call_function, CAR, CDR, ENTITY_MULTIPLY_P, EXPRESSION, expression_syntax, expression_to_string(), is_syntax_call, is_syntax_reference, NIL, pips_assert, pips_internal_error, reference_variable, sizeof_value_entity_p(), syntax_call, syntax_reference, and syntax_tag.

Referenced by pointer_binary_operation_to_transformer().

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

◆ iabs_to_transformer()

static transformer iabs_to_transformer ( entity  v,
expression  expr,
transformer  pre,
bool  is_internal 
)
static
Parameters
exprassumed to be a value

Definition at line 1693 of file expression.c.

1697 {
1700  transformer etf = integer_expression_to_transformer(tv, expr, pre, is_internal);
1701  Pvecteur vlb1 = vect_new((Variable) tv, VALUE_ONE);
1702  Pvecteur vlb2 = vect_new((Variable) tv, VALUE_MONE);
1703 
1704  pips_debug(8, "begin\n");
1705 
1706 
1707  vect_add_elem(&vlb1, (Variable) v, VALUE_MONE);
1708  vect_add_elem(&vlb2, (Variable) v, VALUE_MONE);
1709 
1710  tf = transformer_inequality_add(tf, vlb1);
1711  tf = transformer_inequality_add(tf, vlb2);
1713  free_transformer(etf);
1714 
1715  ifdebug(8) {
1716  pips_debug(8, "result:\n");
1717  dump_transformer(tf);
1718  pips_debug(8, "end\n");
1719  }
1720 
1721  return tf;
1722 }

References dump_transformer, entity_type, free_transformer(), ifdebug, integer_expression_to_transformer(), make_local_temporary_value_entity(), pips_debug, transformer_identity(), transformer_inequality_add(), transformer_safe_image_intersection(), VALUE_MONE, VALUE_ONE, vect_add_elem(), and vect_new().

Referenced by integer_unary_operation_to_transformer().

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

◆ integer_binary_operation_to_transformer()

static transformer integer_binary_operation_to_transformer ( entity  e,
entity  op,
expression  e1,
expression  e2,
transformer  pre,
bool  is_internal 
)
static

Prologue more or less necessary for all non affine operators

post1 == pre2...

Case disjunction to use only positive intervals + sign information

either t1 or t2 is undefined: so tf is most likely undefined

Old function call

Definition at line 3274 of file expression.c.

3280 {
3282 
3283  pips_debug(8, "Begin\n");
3284 
3285  if(ENTITY_PLUS_P(op) || ENTITY_MINUS_P(op)
3286  || ENTITY_PLUS_C_P(op) || ENTITY_MINUS_C_P(op)) {
3287  tf = addition_operation_to_transformer(e, e1, e2, pre,
3288  ENTITY_PLUS_P(op) || ENTITY_PLUS_C_P(op),
3289  is_internal);
3290  }
3292  tf = update_operation_to_transformer(e, op, e1, e2, pre, is_internal);
3293  }
3294  else if(ENTITY_MULTIPLY_P(op)) {
3295  tf = integer_multiply_to_transformer(e, e1, e2, pre, is_internal);
3296  }
3297  else if(ENTITY_MODULO_P(op) || ENTITY_C_MODULO_P(op)) {
3298  tf = modulo_to_transformer(e, e1, e2, pre, is_internal);
3299  }
3300  else if(ENTITY_DIVIDE_P(op)) {
3301  if(!get_bool_property("SEMANTICS_ASSUME_POSITIVE_REMAINDERS")) {
3302  /* Prologue more or less necessary for all non affine operators */
3303  entity v = e; // Formal parameter name should be fixed
3306  transformer t1 = safe_integer_expression_to_transformer(v1, e1, pre1, is_internal);
3309  transformer t2 = safe_integer_expression_to_transformer(v2, e2, pre2, is_internal);
3310 
3311  if(transformer_empty_p(t1) || transformer_empty_p(t2)) {
3312  // Some exception occurs during the evaluation of e1 or e2
3313  // For instance, a zero divide or an exit in a called function
3314  tf = transformer_empty();
3315  }
3316  else if(!transformer_undefined_p(t1) && !transformer_undefined_p(t2)) {
3317  int lb1 = 0, ub1 = 0, lb2 = 0, ub2 = 0;
3318  tf = transformer_combine(copy_transformer(t1), t2);
3319  /* post1 == pre2... */
3320  transformer post1 = transformer_range(transformer_apply(pre1, t1));
3321  transformer post2 = transformer_range(transformer_apply(post1, t2));
3322  // transformer post2 = transformer_range(tf);
3325 
3326  /* Case disjunction to use only positive intervals + sign information */
3327  //struct interval_product cases[4];
3328  //int ncase = 0;
3329  //break_intervals_into_positive_intervals(lb1, ub1, lb2, ub2, cases, &ncase, true);
3330  //tf = process_intervals_for_divide(tf, v, v1, v2, cases, ncase);
3331  tf = process_bounds_for_divide(tf, v, v1, lb1, ub1, v2, lb2, ub2);
3332  }
3333  else {
3334  /* either t1 or t2 is undefined: so tf is most likely undefined */
3335  ;
3336  }
3337  }
3338  else {
3339  /* Old function call */
3340  tf = integer_divide_to_transformer(e, e1, e2, pre, is_internal);
3341  }
3342  }
3343  else if(ENTITY_POWER_P(op)) {
3344  tf = integer_power_to_transformer(e, e1, e2, pre, is_internal);
3345  }
3346  else if(ENTITY_ASSIGN_P(op)) {
3347  tf = assign_operation_to_transformer(e, e1, e2, pre);
3348  }
3349  else if(ENTITY_LEFT_SHIFT_P(op)) {
3350  tf = integer_left_shift_to_transformer(e, e1, e2, pre, is_internal);
3351  }
3352  else if(ENTITY_RIGHT_SHIFT_P(op)) {
3353  tf = integer_right_shift_to_transformer(e, e1, e2, pre, is_internal);
3354  }
3355 
3356  pips_debug(8, "End with tf=%p\n", tf);
3357 
3358  return tf;
3359 }
#define ENTITY_PLUS_UPDATE_P(e)
#define ENTITY_DIVIDE_P(e)
#define ENTITY_POWER_P(e)
#define ENTITY_LEFT_SHIFT_P(e)
#define ENTITY_RIGHT_SHIFT_P(e)
#define ENTITY_MINUS_UPDATE_P(e)
#define ENTITY_C_MODULO_P(e)
#define ENTITY_MODULO_P(e)
static transformer update_operation_to_transformer(entity v, entity op, expression e1, expression e2, transformer pre, bool is_internal)
v = (e1 = e1 op e2) ; e1 must be a reference; does not compute information for dereferenced pointers ...
Definition: expression.c:590
static transformer integer_divide_to_transformer(entity e, expression arg1, expression arg2, transformer pre, bool is_internal)
More could be done along the line of integer_multiply_to_transformer()...
Definition: expression.c:1780
static transformer integer_right_shift_to_transformer(entity e, expression arg1, expression arg2, transformer pre, bool is_internal)
More could be done along the line of integer_left_shift_to_transformer()...
Definition: expression.c:1827
static transformer modulo_to_transformer(entity e, expression arg1, expression arg2, transformer pre, bool is_internal __attribute__((unused)))
Modulo and integer division.
Definition: expression.c:1580
static transformer integer_left_shift_to_transformer(entity v, expression e1, expression e2, transformer prec, bool is_internal)
Assumes that e1 and e2 are integer expressions, i.e.
Definition: expression.c:2303
static transformer integer_power_to_transformer(entity e, expression arg1, expression arg2, transformer prec, bool is_internal)
Definition: expression.c:2444
static transformer process_bounds_for_divide(transformer tf, entity v, entity v1, int lb1, int ub1, entity v2, int lb2, int ub2)
Auxiliary function for non-affine operators such as divide, multiply, modulo...
Definition: expression.c:3141
static transformer integer_multiply_to_transformer(entity v, expression e1, expression e2, transformer prec, bool is_internal)
Assumes that e1 and e2 are integer expressions, i.e.
Definition: expression.c:1880
void integer_value_and_precondition_to_integer_interval(entity, transformer, int *, int *)
Should be used by previous function, integer_expression_and_precondition_to_integer_interval()
Definition: utils.c:427

References addition_operation_to_transformer(), assign_operation_to_transformer(), copy_transformer(), ENTITY_ASSIGN_P, ENTITY_C_MODULO_P, ENTITY_DIVIDE_P, ENTITY_LEFT_SHIFT_P, ENTITY_MINUS_C_P, ENTITY_MINUS_P, ENTITY_MINUS_UPDATE_P, ENTITY_MODULO_P, ENTITY_MULTIPLY_P, ENTITY_PLUS_C_P, ENTITY_PLUS_P, ENTITY_PLUS_UPDATE_P, ENTITY_POWER_P, ENTITY_RIGHT_SHIFT_P, entity_type, get_bool_property(), integer_divide_to_transformer(), integer_left_shift_to_transformer(), integer_multiply_to_transformer(), integer_power_to_transformer(), integer_right_shift_to_transformer(), integer_value_and_precondition_to_integer_interval(), make_local_temporary_value_entity(), modulo_to_transformer(), pips_debug, process_bounds_for_divide(), safe_integer_expression_to_transformer(), transformer_apply(), transformer_combine(), transformer_empty(), transformer_empty_p(), transformer_identity(), transformer_range(), transformer_safe_apply(), transformer_undefined, transformer_undefined_p, and update_operation_to_transformer().

Referenced by integer_call_expression_to_transformer(), and logical_binary_function_to_transformer().

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

◆ integer_call_expression_to_transformer()

static transformer integer_call_expression_to_transformer ( entity  e,
expression  expr,
transformer  pre,
bool  is_internal 
)
static

tests are organized to trap 0-ary user-defined functions as well as binary min and max

FI: should only happen for C code because int are often used as bool since there was no other way before C99. Quite time consuming here because it is applied to an int and not a bool argument.

FI: it might be useful to handle here the bit wise XOR as in logical_binary_operation_to_transformer().

No need to use effects here. It will be done at a higher level

integer constant must have been detected earlier as linear (affine) expressions but there might be nullary intrinsic such as rand()

Parameters
preneeded to compute effects for user calls
is_internalPredicate on current store assumed not modified by expr's side effects

Definition at line 3361 of file expression.c.

3367 {
3368  syntax sexpr = expression_syntax(expr);
3369  call c = syntax_call(sexpr);
3370  entity f = call_function(c);
3371  list args = call_arguments(c);
3373  int arity = gen_length(args);
3374 
3375  pips_debug(8, "Begin with precondition %p\n", pre);
3376 
3377  /* tests are organized to trap 0-ary user-defined functions as well as
3378  binary min and max */
3379 
3380  // arity unknown, but greater than 2?
3381  if(ENTITY_MIN0_P(f) || ENTITY_MIN_P(f)) {
3382  tf = min0_to_transformer(e, args, pre, is_internal);
3383  }
3384  else if(ENTITY_C_MIN_P(f)) {
3385  args=CDR(args);
3386  --arity;
3387  tf = min0_to_transformer(e,args,pre,is_internal);
3388  }
3389  else if(ENTITY_MAX0_P(f) || ENTITY_MAX_P(f)) {
3390  tf = max0_to_transformer(e, args, pre, is_internal);
3391  }
3392  else if(ENTITY_C_MAX_P(f)) {
3393  args=CDR(args);
3394  --arity;
3395  tf = max0_to_transformer(e,args,pre,is_internal);
3396  }
3397  else if(ENTITY_COMMA_P(f)) {
3398  // is_internal is dropped...
3399  tf = any_expressions_to_transformer(e, args, pre);
3400  }
3401  // arity==3
3402  else if(ENTITY_CONDITIONAL_P(f)) {
3403  tf = any_conditional_to_transformer(e, args, pre);
3404  }
3405  // arity==1
3406  else if(ENTITY_NOT_P(f)) {
3407  /* FI: should only happen for C code because int are often used
3408  as bool since there was no other way before C99. Quite time
3409  consuming here because it is applied to an int and not a
3410  bool argument. */
3411  tf = logical_not_to_transformer(e, args, pre);
3412  }
3413  // arity==2
3414  else if(ENTITY_BITWISE_XOR_P(f)) {
3415  /* FI: it might be useful to handle here the bit wise XOR as in
3416  logical_binary_operation_to_transformer(). */
3417  tf = bitwise_xor_to_transformer(e, args, pre);
3418  }
3419  // arity ==1
3420  else if(ENTITY_RAND_P(f)) {
3421  tf = transformer_identity();
3423  }
3424  // arity = 2
3425  else if(ENTITY_MODULO_P(f) || ENTITY_C_MODULO_P(f)) {
3426  expression arg1 = EXPRESSION(CAR(args));
3427  expression arg2 = EXPRESSION(CAR(CDR(args)));
3428  tf = modulo_to_transformer(e, arg1, arg2, pre, false);
3429  }
3430  else if(value_code_p(entity_initial(f))) {
3432  tf = user_function_call_to_transformer(e, expr, pre);
3433  }
3434  else {
3435  /* No need to use effects here. It will be done at a higher level */
3436  ;
3437  }
3438  }
3439  else if(arity==0) {
3440  /* integer constant must have been detected earlier as linear (affine)
3441  expressions but there might be nullary intrinsic such as rand() */
3442  tf = integer_nullary_operation_to_transformer(e, f, pre, is_internal);
3443  }
3444  else if(arity==1) {
3445  expression e1 = EXPRESSION(CAR(args));
3446  tf = integer_unary_operation_to_transformer(e, f, e1, pre, is_internal);
3447  }
3448  else if(arity==2) {
3450  && constant_path_analyzed_p()) {
3451  tf = lhs_expression_to_transformer(e, expr, pre);
3452  }
3453  else {
3454  expression e1 = EXPRESSION(CAR(args));
3455  expression e2 = EXPRESSION(CAR(CDR(args)));
3456  tf = integer_binary_operation_to_transformer(e, f, e1, e2, pre, is_internal);
3457  }
3458  }
3459 
3460  pips_debug(8, "End with tf=%p\n", tf);
3461 
3462  return tf;
3463 }
transformer transformer_add_inequality_with_integer_constraint(transformer tf, entity v, long long int cst, bool less_than_p)
Add the inequality v <= cst or v >= cst.
Definition: basic.c:477
#define ENTITY_MAX0_P(e)
#define ENTITY_C_MAX_P(e)
#define ENTITY_CONDITIONAL_P(e)
#define ENTITY_NOT_P(e)
#define ENTITY_RAND_P(e)
#define ENTITY_BITWISE_XOR_P(e)
#define ENTITY_MIN0_P(e)
static transformer max0_to_transformer(entity e, list args, transformer pre, bool is_internal)
Definition: expression.c:2728
transformer any_expressions_to_transformer(entity v, list expl, transformer pre)
Compute the transformer associated to a list of expressions such as "i=0, j = 1;".
Definition: expression.c:5754
transformer bitwise_xor_to_transformer(entity v, list args, transformer pre)
returns the transformer associated to a C bitwise xor, ^, applied to two integer argument,...
Definition: expression.c:5619
transformer any_conditional_to_transformer(entity v, list args, transformer pre)
Take care of the returned value.
Definition: expression.c:5524
transformer logical_not_to_transformer(entity v, list args, transformer pre)
returns the transformer associated to a C logical not, !, applied to an integer argument,...
Definition: expression.c:5571
static transformer integer_nullary_operation_to_transformer(entity e __attribute__((unused)), entity f __attribute__((unused)), transformer pre __attribute__((unused)), bool is_internal __attribute__((unused)))
FI: this function is no longer useful (11 August 2013)
Definition: expression.c:2856
static transformer integer_unary_operation_to_transformer(entity e, entity op, expression e1, transformer pre, bool is_internal)
Definition: expression.c:2880
transformer lhs_expression_to_transformer(entity e, expression lhs, transformer pre)
This function deals with e1.e2 and e1->e2, not with simple references such as x or a[i].
Definition: expression.c:6262
static transformer integer_binary_operation_to_transformer(entity e, entity op, expression e1, expression e2, transformer pre, bool is_internal)
Definition: expression.c:3274
static transformer min0_to_transformer(entity e, list args, transformer pre, bool is_internal)
Definition: expression.c:2720
bool constant_path_analyzed_p(void)
Definition: value.c:330

References any_conditional_to_transformer(), any_expressions_to_transformer(), bitwise_xor_to_transformer(), call_arguments, call_function, CAR, CDR, constant_path_analyzed_p(), ENTITY_BITWISE_XOR_P, ENTITY_C_MAX_P, ENTITY_C_MIN_P, ENTITY_C_MODULO_P, ENTITY_COMMA_P, ENTITY_CONDITIONAL_P, ENTITY_FIELD_P, entity_initial, ENTITY_MAX0_P, ENTITY_MAX_P, ENTITY_MIN0_P, ENTITY_MIN_P, ENTITY_MODULO_P, ENTITY_NOT_P, ENTITY_POINT_TO_P, ENTITY_RAND_P, EXPRESSION, expression_syntax, f(), gen_length(), get_bool_property(), integer_binary_operation_to_transformer(), integer_nullary_operation_to_transformer(), integer_unary_operation_to_transformer(), lhs_expression_to_transformer(), logical_not_to_transformer(), max0_to_transformer(), min0_to_transformer(), modulo_to_transformer(), pips_debug, SEMANTICS_INTERPROCEDURAL, syntax_call, transformer_add_inequality_with_integer_constraint(), transformer_identity(), transformer_undefined, user_function_call_to_transformer(), value_code_p, and VALUE_ZERO.

Referenced by integer_expression_to_transformer().

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

◆ integer_divide_to_transformer()

static transformer integer_divide_to_transformer ( entity  e,
expression  arg1,
expression  arg2,
transformer  pre,
bool  is_internal 
)
static

More could be done along the line of integer_multiply_to_transformer()...

when need arises.

pips_assert("Precondition is unused", transformer_undefined_p(pre));

must be duplicated right now because it will be renamed and checked at the same time by value_mappings_compatible_vector_p()

Definition at line 1780 of file expression.c.

1785 {
1787  normalized n1 = NORMALIZE_EXPRESSION(arg1);
1788 
1789  pips_debug(8, "begin with is_internal=%s\n",
1790  bool_to_string(is_internal));
1791 
1792  /* pips_assert("Precondition is unused", transformer_undefined_p(pre)); */
1793  pips_assert("Shut up the compiler", pre==pre);
1794 
1797  int d = integer_constant_expression_value(arg2);
1798  /* must be duplicated right now because it will be
1799  renamed and checked at the same time by
1800  value_mappings_compatible_vector_p() */
1801  Pvecteur vlb =
1803  Pvecteur vub = vect_dup(normalized_linear(n1));
1806 
1807  vect_add_elem(&vlb, (Variable) e, int_to_value(d));
1808  vect_add_elem(&vub, (Variable) e, int_to_value(-d));
1809  vect_add_elem(&vub, TCST, int_to_value(1-d));
1810  clb = contrainte_make(vlb);
1811  cub = contrainte_make(vub);
1812  clb->succ = cub;
1813  tf = make_transformer(NIL,
1815  }
1816 
1817  ifdebug(8) {
1818  pips_debug(8, "result:\n");
1819  dump_transformer(tf);
1820  pips_debug(8, "end\n");
1821  }
1822 
1823  return tf;
1824 }
#define int_to_value(i)
end LINEAR_VALUE_IS_INT
string bool_to_string(bool)
Definition: string.c:243
#define NORMALIZE_EXPRESSION(e)
bool integer_constant_expression_p(expression e)
positive integer constant expression: call to a positive constant or to a sum of positive integer con...
Definition: expression.c:903
int integer_constant_expression_value(expression e)
Definition: expression.c:1545
#define normalized_linear_p(x)
Definition: ri.h:1779
#define normalized_linear(x)
Definition: ri.h:1781

References bool_to_string(), contrainte_make(), CONTRAINTE_UNDEFINED, dump_transformer, ifdebug, int_to_value, integer_constant_expression_p(), integer_constant_expression_value(), make_predicate(), make_transformer(), NIL, NORMALIZE_EXPRESSION, normalized_linear, normalized_linear_p, pips_assert, pips_debug, sc_make(), Scontrainte::succ, TCST, transformer_undefined, value_mappings_compatible_vector_p(), VALUE_MONE, vect_add_elem(), vect_dup(), and vect_multiply().

Referenced by integer_binary_operation_to_transformer().

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

◆ integer_expression_to_transformer()

transformer integer_expression_to_transformer ( entity  v,
expression  expr,
transformer  pre,
bool  is_internal 
)

Do check wrt to value mappings...

if you are not dealing with interprocedural issues

Assume: e is a value

Is it really useful to keep using this function which does not take the precondition into acount?

vect_rm(ve);

Parameters
exprxpr
prere
is_internals_internal

Definition at line 3476 of file expression.c.

3482 {
3484  normalized n = NORMALIZE_EXPRESSION(expr);
3485  syntax sexpr = expression_syntax(expr);
3486 
3487  pips_debug(8, "begin with precondition %p for expression: ", pre);
3488  ifdebug(8) print_expression(expr);
3489 
3490  /* Assume: e is a value */
3491 
3492  if(normalized_linear_p(n)) {
3493  /* Is it really useful to keep using this function which does not
3494  take the precondition into acount? */
3495  if(transformer_undefined_p(pre)) {
3496  tf = simple_affine_to_transformer(v, (Pvecteur) normalized_linear(n), is_internal);
3497  }
3498  else {
3500  if(transformer_undefined_p(tfl)) {
3502  }
3503 
3504  tf = transformer_combine(copy_transformer(pre), tfl);
3505  free_transformer(tfl);
3506  }
3507  }
3508  else if(syntax_call_p(sexpr)) {
3509  tf = integer_call_expression_to_transformer(v, expr, pre, is_internal);
3510  }
3511  else if(syntax_reference_p(sexpr)) {
3512  //entity e = reference_variable(syntax_reference(sexpr));
3513  reference r = syntax_reference(sexpr);
3514  tf = generic_reference_to_transformer(v, r, pre, is_internal);
3515  }
3516  else if(syntax_cast_p(sexpr)) {
3517  cast c = syntax_cast(sexpr);
3518  type ct = cast_type(c);
3519  expression cexp = cast_expression(c);
3520  type cexpt = expression_to_type(cexp);
3521  if (type_equal_p(ct, cexpt))
3522  tf = integer_expression_to_transformer(v, cexp, pre, is_internal);
3523  else
3524  tf = transformer_undefined;
3525  free_type(cexpt);
3526 
3527  }
3528  else if(syntax_sizeofexpression_p(sexpr)) {
3529  if(get_bool_property("EVAL_SIZEOF")) {
3531  value val = EvalSizeofexpression(soe);
3532  if(value_constant_p(val) && constant_int_p(value_constant(val))) {
3533  long long int i = constant_int(value_constant(val));
3534  tf = transformer_identity();
3536  }
3537  }
3538  else
3539  tf = transformer_undefined;
3540  }
3541  else {
3542  /* vect_rm(ve); */
3543  tf = transformer_undefined;
3544  }
3545 
3546  pips_debug(8, "end with tf=%p\n", tf);
3547 
3548  return tf;
3549 }
value EvalSizeofexpression(sizeofexpression soe)
Definition: eval.c:210
bool type_equal_p(type, type)
Definition: type.c:547
#define value_constant(x)
Definition: ri.h:3073
#define constant_int(x)
Definition: ri.h:850
#define syntax_sizeofexpression_p(x)
Definition: ri.h:2740
#define value_constant_p(x)
Definition: ri.h:3071
#define constant_int_p(x)
Definition: ri.h:848
#define cast_type(x)
Definition: ri.h:745
static transformer integer_call_expression_to_transformer(entity e, expression expr, transformer pre, bool is_internal)
Definition: expression.c:3361
transformer expression_effects_to_transformer(expression expr)
Definition: expression.c:3465
transformer simple_affine_to_transformer(entity e, Pvecteur a, bool is_internal)
INTEGER EXPRESSIONS.
Definition: expression.c:1167

References cast_expression, cast_type, constant_int, constant_int_p, copy_transformer(), EvalSizeofexpression(), expression_effects_to_transformer(), expression_syntax, expression_to_type(), free_transformer(), free_type(), generic_reference_to_transformer(), get_bool_property(), ifdebug, integer_call_expression_to_transformer(), NORMALIZE_EXPRESSION, normalized_linear, normalized_linear_p, pips_debug, print_expression(), simple_affine_to_transformer(), syntax_call_p, syntax_cast, syntax_cast_p, syntax_reference, syntax_reference_p, syntax_sizeofexpression, syntax_sizeofexpression_p, transformer_add_equality_with_integer_constant(), transformer_combine(), transformer_identity(), transformer_undefined, transformer_undefined_p, type_equal_p(), value_constant, and value_constant_p.

Referenced by any_expression_to_transformer(), iabs_to_transformer(), integer_expression_and_precondition_to_integer_interval(), integer_minmax_to_transformer(), and safe_integer_expression_to_transformer().

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

◆ integer_left_shift_to_transformer()

static transformer integer_left_shift_to_transformer ( entity  v,
expression  e1,
expression  e2,
transformer  prec,
bool  is_internal 
)
static

Assumes that e1 and e2 are integer expressions, i.e.

explicit casting is supposed to be used.

This piece of code has been copied and pasted from integer_multiply_to_transformer(). Common issues like evaluating the intervals for the values of the arguments should be factored out.

FI: I had to switch the arguments to satisfy a reasonnable assert in image_intersection(), but the switch may be detrimental to memory allocation.

The numerical value of expression e2 is known: v = v1*2^lb2

lb2<0

The value of v belongs to a bounded interval

Definition at line 2303 of file expression.c.

2308 {
2310  // FI: ultimate_type should be called? Or int assumed?
2312  transformer ipre = transformer_undefined_p(prec)?
2314  transformer t1 = safe_integer_expression_to_transformer(v1, e1, ipre, is_internal);
2316  transformer npre = transformer_safe_apply(t1, ipre);
2317  transformer t2 = safe_integer_expression_to_transformer(v2, e2, npre, is_internal);
2318  //transformer pre = transformer_undefined_p(ipre)? transformer_identity() :
2319  // copy_transformer(ipre);
2320  transformer pre = ipre;
2321 
2322  pips_debug(8, "Begin\n");
2323 
2325  intptr_t lb1 = 0;
2326  intptr_t ub1 = 0;
2327  intptr_t lb2 = 0;
2328  intptr_t ub2 = 0;
2329 
2330  /* FI: I had to switch the arguments to satisfy a reasonnable
2331  assert in image_intersection(), but the switch may be
2332  detrimental to memory allocation. */
2333  //t1 = transformer_safe_image_intersection(pre, t1);
2334  //t2 = transformer_safe_image_intersection(pre, t2);
2335  t1 = transformer_range(transformer_apply(pre, t1));
2336  t2 = transformer_range(transformer_apply(pre, t2));
2337 
2338  (void) precondition_minmax_of_value(v1, t1, &lb1, &ub1);
2339  (void) precondition_minmax_of_value(v2, t2, &lb2, &ub2);
2340 
2341  if(lb2==ub2) {
2342  /* The numerical value of expression e2 is known: v = v1*2^lb2 */
2343  Pvecteur veq = vect_new((Variable) v, VALUE_MONE);
2344 
2345  if(lb2>=0) {
2346  vect_add_elem(&veq, (Variable) v1,
2347  value_lshift((Value) 1, (Value) lb2));
2348  }
2349  else /* lb2<0 */ {
2350  // FI: Should look at the norm; seems to return 0 with gdb
2351  ;
2352  }
2353 
2354  tf = transformer_equality_add(t1, veq);
2355  free_transformer(t2);
2356  }
2357  else if(0<lb2 && ub2<INT_MAX) {
2358  /* The value of v belongs to a bounded interval */
2359  if(0<=lb1) {
2360  // v1 is positive: v1*2^lb2 <= v <= v1*2^ub2
2361  Pvecteur veq1 = vect_new((Variable) v, VALUE_MONE);
2362  Pvecteur veq2 = vect_new((Variable) v, VALUE_ONE);
2363  vect_add_elem(&veq1, (Variable) v1,
2364  value_lshift((Value) 1, (Value) lb2));
2365  vect_add_elem(&veq2, (Variable) v1,
2366  -value_lshift((Value) 1, (Value) ub2));
2367  tf = transformer_inequality_add(t1, veq1);
2368  tf = transformer_inequality_add(t1, veq2);
2369  free_transformer(t2);
2370  }
2371  else if(ub1<=0) {
2372  // v1 is negative: v1*2^ub2 <= v <= v1*2^lb2
2373  Pvecteur veq1 = vect_new((Variable) v, VALUE_MONE);
2374  Pvecteur veq2 = vect_new((Variable) v, VALUE_ONE);
2375  vect_add_elem(&veq1, (Variable) v1,
2376  value_lshift((Value) 1, (Value) ub2));
2377  vect_add_elem(&veq2, (Variable) v1,
2378  -value_lshift((Value) 1, (Value) lb2));
2379  tf = transformer_inequality_add(t1, veq1);
2380  tf = transformer_inequality_add(t1, veq2);
2381  free_transformer(t2);
2382  }
2383  else {
2384  // No information is available because the sign of v1 is
2385  // unknown
2386  ;
2387  }
2388  }
2389  else {
2390  // Let's hope that the sign of v2 is known as well as the sign
2391  // of v1. It does not matter if v1 is known exactly or not
2392  // a new transformer must be built
2393  //free_transformer(t1);
2394  free_transformer(t2);
2395  //transformer tf = transformer_identity();
2396 
2397  if(lb2>=0 && lb1>=1) {
2398  // The value of v is greater than the value of v1 multiplied
2399  // by 2
2400  tf = transformer_add_inequality_with_affine_term(t1, v, v1, 2, 0, false);
2401  }
2402  else if(lb2>=0 && lb1==0) {
2403  // The value of v is 0
2404  tf = transformer_add_inequality(t1, v1, v, false);
2405  //tf = transformer_add_equality_with_integer_constant(tf, v, 0);
2406  }
2407  else if(lb2>0 && ub1<0) {
2408  // The value of v is lesser than the value of v1
2409  tf = transformer_add_inequality(t1, v, v1, true);
2410  }
2411  else if(lb2>0 && ub1==0) {
2412  // The value of v is lesser than the value of v1
2413  tf = transformer_add_inequality(t1, v, v1, false);
2414  }
2415  else if(ub2<0) {
2416  // The value of v is zero
2417  free_transformer(t1);
2418  tf = transformer_identity();
2420  }
2421  else // nothing is know about v2: the sign of v1 is preserved
2422  // To be checked in C standard...
2423  if(0<=lb1)
2425  else if(ub1<=0)
2427  }
2428  }
2429  else if(!transformer_undefined_p(t1)) {
2430  free_transformer(t1);
2431  }
2432  else if(!transformer_undefined_p(t2)) {
2433  free_transformer(t2);
2434  }
2435 
2436  free_transformer(pre);
2437 
2438  pips_debug(8, "End with tf=%p\n", tf);
2439  ifdebug(8) (void) dump_transformer(tf);
2440 
2441  return tf;
2442 }
#define value_lshift(v1, v2)
transformer transformer_add_inequality_with_affine_term(transformer tf, entity v, entity x, int a, int cst, bool less_than_p)
Add the inequality v <= a x + cst or v >= a x + cst.
Definition: basic.c:496
transformer transformer_add_inequality(transformer tf, entity v1, entity v2, bool strict_p)
Add the equality v1 <= v2 or v1 < v2.
Definition: basic.c:464

References dump_transformer, entity_type, free_transformer(), ifdebug, intptr_t, make_local_temporary_value_entity(), pips_debug, precondition_minmax_of_value(), safe_integer_expression_to_transformer(), transformer_add_equality_with_integer_constant(), transformer_add_inequality(), transformer_add_inequality_with_affine_term(), transformer_add_inequality_with_integer_constraint(), transformer_apply(), transformer_equality_add(), transformer_identity(), transformer_inequality_add(), transformer_range(), transformer_safe_apply(), transformer_undefined, transformer_undefined_p, value_lshift, VALUE_MONE, VALUE_ONE, vect_add_elem(), and vect_new().

Referenced by integer_binary_operation_to_transformer().

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

◆ integer_minmax_to_transformer()

static transformer integer_minmax_to_transformer ( entity  v,
list  args,
transformer  pre,
bool  is_min,
bool  is_internal 
)
static
Parameters
argsalue for minmax

Definition at line 2655 of file expression.c.

2660 {
2662  list cexpr;
2663  intptr_t bound = is_min? LONG_MAX : LONG_MIN;
2664 
2665  pips_debug(8, "begin for %s %s\n",
2666  is_min? "minimum" : "maximum",
2667  is_internal? "intraprocedural" : "interprocedural");
2668 
2669  for(cexpr = args; !ENDP(cexpr); POP(cexpr)) {
2670  expression arg = EXPRESSION(CAR(cexpr));
2671  intptr_t lb, ub;
2672  if(precondition_minmax_of_expression(arg, pre, &lb, &ub)) {
2673  // FI: useless precision loss, anticipating
2674  // transformer_add_inequality_with+integer_constraint()
2675  bound = is_min? (MIN(bound, lb)) : (MAX(bound, ub));
2676  }
2677  else {
2678  bound = is_min? LONG_MIN : LONG_MAX;
2679  }
2682  is_internal);
2683  Pvecteur vineq = vect_new((Variable) tv, (Value) VALUE_ONE);
2684 
2685  vect_add_elem(&vineq, (Variable) v, VALUE_MONE);
2686 
2687  if(is_min) {
2688  vineq = vect_multiply(vineq, VALUE_MONE);
2689  }
2690 
2691  tf = transformer_inequality_add(tf, vineq);
2693  free_transformer(etf);
2694  }
2695 
2696  if(bound!=LONG_MIN && bound!=LONG_MAX) { // FI: this test does not
2697  // seem to work as expected...
2698  int b = (int) bound;
2699  if((intptr_t) b == bound) { // FI: for safety...
2700  //tf = transformer_add_inequality_with_integer_constant(tf, v, bound, is_min);
2702  }
2703  }
2704 
2705  // FI: not strong enough to remove stupid redundancy. See
2706  // Semantics/minmax3
2707  // I do not dare add a stronger normalization because it could
2708  // impact the execution time too much...
2709  //tf = transformer_normalize(tf, 2);
2710 
2711  ifdebug(8) {
2712  pips_debug(8, "result:\n");
2713  dump_transformer(tf);
2714  pips_debug(8, "end\n");
2715  }
2716 
2717  return tf;
2718 }
#define MIN(x, y)
minimum and maximum if they are defined somewhere else, they are very likely to be defined the same w...
@ is_min
Definition: optimize.c:710
bool precondition_minmax_of_expression(expression exp, transformer tr, intptr_t *pmin, intptr_t *pmax)
compute integer bounds pmax, pmin of expression exp under preconditions tr require value mappings set...
Definition: expression.c:5818
#define MAX(x, y)
Definition: string.c:110

References CAR, dump_transformer, ENDP, entity_type, EXPRESSION, free_transformer(), ifdebug, int, integer_expression_to_transformer(), intptr_t, is_min, make_local_temporary_value_entity(), MAX, MIN, pips_debug, POP, precondition_minmax_of_expression(), transformer_add_inequality_with_integer_constraint(), transformer_identity(), transformer_inequality_add(), transformer_safe_image_intersection(), VALUE_MONE, VALUE_ONE, vect_add_elem(), vect_multiply(), and vect_new().

Referenced by max0_to_transformer(), and min0_to_transformer().

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

◆ integer_multiply_to_transformer()

static transformer integer_multiply_to_transformer ( entity  v,
expression  e1,
expression  e2,
transformer  prec,
bool  is_internal 
)
static

Assumes that e1 and e2 are integer expressions, i.e.

explicit casting is supposed to be used Better results might be obtained when e1 is an affine function of e2 or vice-versa as can occur when convex hulls generate coupling between variables. See non_linear11.f, 22L1=9L2+40, 1<=L1<=10. The smallest possible value is -2 and not -20.

FI: I had to switch the arguments to satisfy a reasonnable assert in image_intersection(), but the switch may be detrimental to memory allocation.

The numerical value of expression e1 is known: v = lb1*v2

The numerical value of expression e2 is known: v = lb2*v1

FI: This should now be obsolete... but it is not when the signs are unknown

Do we have range information?

let's try to exploit some properties of squaring, but the detection is poor. For instance 2*i*i won't be identified as a square.

let's assume no impact from side effects

v is greater than v1 and -v1. This makes v>=0 redundant

Memory leak with tf...

The result is always positive: v>=0

v is less than v1 and -v1. This makes v<=0 redundant

Memory leak with tf...

The result is always negative: v<=0

The result is always positive: v>=0

The result is always negative: v<=0

Definition at line 1880 of file expression.c.

1885 {
1889  transformer t1 = safe_integer_expression_to_transformer(v1, e1, ipre, is_internal);
1891  transformer npre = transformer_safe_apply(t1, ipre);
1892  transformer t2 = safe_integer_expression_to_transformer(v2, e2, npre, is_internal);
1893  //transformer pre = transformer_undefined_p(ipre)? transformer_identity() :
1894  //copy_transformer(ipre);
1896  ipre;
1897 
1898  pips_debug(8, "Begin\n");
1899 
1900  if(transformer_empty_p(t1) || transformer_empty_p(t2)) {
1901  // Some exception occurs during the evaluation of e1 or e2
1902  // For instance, a zero divide
1903  tf = t1;
1904  t1 = transformer_undefined;
1905  }
1906  else if(!transformer_undefined_p(t1) && !transformer_undefined_p(t2)) {
1907  int lb1 = 0;
1908  int ub1 = 0;
1909  int lb2 = 0;
1910  int ub2 = 0;
1911 
1912  /*
1913  * v1 and v2 are temp value,
1914  * so don't have normalize
1915  * so expression_and_precondition_to_integer_interval can't say anything interesting
1916  */
1917  //expression ev1 = entity_to_expression(v1);
1918  //expression ev2 = entity_to_expression(v2);
1919 
1920  /* FI: I had to switch the arguments to satisfy a reasonnable
1921  assert in image_intersection(), but the switch may be
1922  detrimental to memory allocation. */
1923  //t1 = transformer_safe_image_intersection(pre, t1);
1924  //t2 = transformer_safe_image_intersection(pre, t2);
1926  //t2 = transformer_range(transformer_apply(pre, t2));
1928 
1929  // Nelson Lossing: in some cases, these calls are useless and
1930  // return [MIN,MAX] because ev1 and ev2 are built with temporary values
1931  // In his case, it works if ev1 and ev2 are replaced by e1 and e2
1932  //expression_and_precondition_to_integer_interval(ev1, t1, &lb1, &ub1);
1933  //expression_and_precondition_to_integer_interval(ev2, t2, &lb2, &ub2);
1934  // FI-> Nelson: there may be a problem, but your are reanalyzing
1935  //e1 and e2, which has just been performed above; and you fail when side
1936  // effects occur (multiply07.c)
1937  //integer_expression_and_precondition_to_integer_interval(e1, p1, &lb1, &ub1);
1938  //integer_expression_and_precondition_to_integer_interval(e2, p2, &lb2, &ub2);
1941  //free_expression(ev1);
1942  //free_expression(ev2);
1943 
1944  if(lb1==ub1) {
1945  /* The numerical value of expression e1 is known: v = lb1*v2 */
1946  Pvecteur veq = vect_new((Variable) v, VALUE_MONE);
1947 
1948  vect_add_elem(&veq, (Variable) v2, (Value) lb1);
1949  tf = transformer_combine(t1, t2);
1950  transformer_equality_add(tf, veq);
1951  t1 = transformer_undefined;
1952  //free_transformer(t1);
1953  }
1954  else if(lb2==ub2) {
1955  /* The numerical value of expression e2 is known: v = lb2*v1 */
1956  Pvecteur veq = vect_new((Variable) v, VALUE_MONE);
1957 
1958  vect_add_elem(&veq, (Variable) v1, (Value) lb2);
1959  tf = transformer_combine(t1, t2);
1960  tf = transformer_equality_add(tf, veq);
1961  t1 = transformer_undefined;
1962  //free_transformer(t2);
1963  }
1964  else if(ub1<=0) { // e1 is negative
1965  if(ub2<=0) { // e2 is negative
1966  // v >= v1 * ub2, v >= ub1 * v2
1967  // v <= v1 * lb2, v <= lb1 * v2 (if lb1 and lb2 exist)
1968  tf = transformer_intersection(t1,t2); // FI: not good if side effects!
1969  tf = transformer_normalize(tf, 2);
1970  tf = transformer_add_inequality_with_linear_term(tf,v,v1,ub2,false);
1971  tf = transformer_add_inequality_with_linear_term(tf,v,v2,ub1,false);
1972  if(lb2>INT_MIN)
1973  tf = transformer_add_inequality_with_linear_term(tf,v,v1,lb2,true);
1974  if(lb1>INT_MIN)
1975  tf = transformer_add_inequality_with_linear_term(tf,v,v2,lb1,true);
1976  }
1977  else if(lb2>=0) { // e2 is positive
1978  // v <= v1 * lb2, v <= ub1 * v2
1979  // v >= v1 * ub2, v >= lb1 * v2 (if lb1 and ub2 exist)
1980  tf = transformer_intersection(t1,t2); // FI: not good if side effects!
1981  tf = transformer_normalize(tf, 2);
1982  tf = transformer_add_inequality_with_linear_term(tf,v,v1,lb2,true);
1983  tf = transformer_add_inequality_with_linear_term(tf,v,v2,ub1,true);
1984  if(ub2<INT_MAX)
1985  tf = transformer_add_inequality_with_linear_term(tf,v,v1,ub2,false);
1986  if(lb1>INT_MIN)
1987  tf = transformer_add_inequality_with_linear_term(tf,v,v2,lb1,false);
1988  }
1989  else { // if lb2 and ub2 are known and their signs are different
1990  if(lb2>INT_MIN && ub2<INT_MAX) {
1991  // v1 * ub2 <= v <= v1 * lb2
1992  tf = transformer_intersection(t1,t2); // FI: not good if side effects!
1993  tf = transformer_normalize(tf, 2);
1994  tf = transformer_add_inequality_with_linear_term(tf,v,v1,ub2,false);
1995  tf = transformer_add_inequality_with_linear_term(tf,v,v1,lb2,true);
1996  ;
1997  }
1998  else {
1999  tf = transformer_identity();
2000  }
2001 
2002  }
2003  }
2004  else if(lb1>=0) {
2005  if(lb2>=0) {
2006  // v >= lb1 * v2, v >= v1 * lb2
2007  // v <= ub1 * v2, v <= v1 * ub2 (if ub1 and ub2 exist)
2008  tf = transformer_intersection(t1,t2); // FI: not good if side effects!
2009  tf = transformer_normalize(tf, 2);
2010  tf = transformer_add_inequality_with_linear_term(tf,v,v2,lb1,false);
2011  tf = transformer_add_inequality_with_linear_term(tf,v,v1,lb2,false);
2012  if(ub1<INT_MAX)
2013  tf = transformer_add_inequality_with_linear_term(tf,v,v2,ub1,true);
2014  if(ub2<INT_MAX)
2015  tf = transformer_add_inequality_with_linear_term(tf,v,v1,ub2,true);
2016  }
2017  else if(ub2<=0) {
2018  // v <= v1 * ub2, v <= lb1 * v2
2019  // v >= v1 * lb2, v >= ub1 * v2 (if ub1 and lb2 exist)
2020  tf = transformer_intersection(t1,t2); // FI: not good if side effects!
2021  tf = transformer_normalize(tf, 2);
2022  tf = transformer_add_inequality_with_linear_term(tf,v,v1,ub2,true);
2023  tf = transformer_add_inequality_with_linear_term(tf,v,v2,lb1,true);
2024  if(lb2>INT_MIN)
2025  tf = transformer_add_inequality_with_linear_term(tf,v,v1,lb2,false);
2026  if(ub1>INT_MAX)
2027  tf = transformer_add_inequality_with_linear_term(tf,v,v2,ub1,false);
2028  ;
2029  }
2030  else {
2031  if(lb2>INT_MIN && ub2<INT_MAX) { // FI: separated test needed
2032  // v1 * lb2 <= v <= v1 * ub2
2033  tf = transformer_intersection(t1,t2); // FI: not good if side effects!
2034  tf = transformer_normalize(tf, 2);
2035  tf = transformer_add_inequality_with_linear_term(tf,v,v1,lb2,false);
2036  tf = transformer_add_inequality_with_linear_term(tf,v,v1,ub2,true);
2037  }
2038  else {
2039  tf = transformer_identity();
2040  }
2041  }
2042  }
2043  else {
2044  /* FI: This should now be obsolete... but it is not when the
2045  signs are unknown */
2046 
2047  /* Do we have range information? */
2048  long long p1 = ((long long) lb1 )*((long long) lb2 );
2049  long long p2 = ((long long) lb1 )*((long long) ub2 );
2050  long long p3 = ((long long) ub1 )*((long long) lb2 );
2051  long long p4 = ((long long) ub1 )*((long long) ub2 );
2052  long long lb = (p2<p1)? p2 : p1;
2053  long long ub = (p2>p1)? p2 : p1;
2054 
2055  lb = (p3<lb)? p3 : lb;
2056  lb = (p4<lb)? p4 : lb;
2057 
2058  ub = (p3>ub)? p3 : ub;
2059  ub = (p4>ub)? p4 : ub;
2060 
2061  //free_transformer(t1);
2062  //free_transformer(t2);
2063 
2064  if(lb > INT_MIN || ub < INT_MAX)
2065  tf = transformer_identity();
2066 
2067  if(lb > INT_MIN) {
2068  Pvecteur vineql = vect_new((Variable) v, VALUE_MONE);
2069 
2070  vect_add_elem(&vineql, TCST, lb);
2072  }
2073  if(ub < INT_MAX) {
2074  Pvecteur vinequ = vect_new((Variable) v, VALUE_ONE);
2075 
2076  vect_add_elem(&vinequ, TCST, -ub);
2077  tf = transformer_inequality_add(tf, vinequ);
2078  }
2079  }
2080  }
2081  else if(!transformer_undefined_p(t1)) {
2082  // free_transformer(t1);
2083  }
2084  else if(!transformer_undefined_p(t2)) {
2085  //free_transformer(t2);
2086  //t2 = transformer_undefined;
2087  }
2088 
2089  free_transformer(pre);
2090 
2091  /* let's try to exploit some properties of squaring, but the
2092  detection is poor. For instance 2*i*i won't be identified as a
2093  square. */
2094  if(transformer_undefined_p(tf)) {
2095  /* let's assume no impact from side effects */
2096  if(expression_equal_p(e1, e2)) {
2097  // FI: we could do a much better job here
2098  // a different function such as integer_square_to_transformer()
2099  // should be called to also generate the first terms
2100  // v>=t, v>=-t, v>=3t-2, v>=-3t-2
2101  // This terms are useful when t is connected because e1 is
2102  // affine and when the programmer plays on the behavior of
2103  // square around 0
2104  // See cavern01.c
2105 
2106  /* v is greater than v1 and -v1. This makes v>=0 redundant */
2107  if(!transformer_undefined_p(t1)) {
2108  tf = transformer_add_inequality(t1, v1, v, false);
2110  v1, VALUE_MONE, VALUE_ZERO,
2111  false);
2112  /* Memory leak with tf... */
2113  tf = transformer_intersection(tf, t1);
2114  }
2115  else {
2116  /* The result is always positive: v>=0 */
2117  Pvecteur vineq = vect_new((Variable) v, VALUE_MONE);
2118  tf = transformer_identity();
2119  tf = transformer_inequality_add(tf, vineq);
2120  }
2121  }
2122  else if(expression_opposite_p(e1, e2)) {
2123  /* v is less than v1 and -v1. This makes v<=0 redundant */
2124  if(!transformer_undefined_p(t1)) {
2125  tf = transformer_add_inequality(t1, v, v1, false);
2127  v1, VALUE_MONE, VALUE_ZERO,
2128  true);
2129  /* Memory leak with tf... */
2130  tf = transformer_intersection(tf, t1);
2131  }
2132  else {
2133  /* The result is always negative: v<=0 */
2134  Pvecteur vineq = vect_new((Variable) v, VALUE_ONE);
2135  tf = transformer_identity();
2136  tf = transformer_inequality_add(tf, vineq);
2137  }
2138  }
2139  }
2140  else {
2141  if(expression_equal_p(e1, e2)) {
2142  /* The result is always positive: v>=0 */
2143  Pvecteur vineq = vect_new((Variable) v, VALUE_MONE);
2144  tf = transformer_inequality_add(tf, vineq);
2145  }
2146  else if(expression_opposite_p(e1, e2)) {
2147  /* The result is always negative: v<=0 */
2148  Pvecteur vineq = vect_new((Variable) v, VALUE_ONE);
2149  tf = transformer_inequality_add(tf, vineq);
2150  }
2151  }
2152 
2153  if(!transformer_undefined_p(t1)) {
2154  free_transformer(t1);
2155  }
2156  if(!transformer_undefined_p(t2)) {
2157  free_transformer(t2);
2158  }
2159 
2160  pips_debug(8, "End with tf=%p\n", tf);
2161  ifdebug(8) (void) dump_transformer(tf);
2162 
2163  return tf;
2164 }
bool expression_opposite_p(expression e1, expression e2)
e1+e2==0, i.e.
Definition: expression.c:1386

References copy_transformer(), dump_transformer, entity_type, expression_equal_p(), expression_opposite_p(), free_transformer(), ifdebug, integer_value_and_precondition_to_integer_interval(), make_local_temporary_value_entity(), pips_debug, safe_integer_expression_to_transformer(), TCST, transformer_add_inequality(), transformer_add_inequality_with_affine_term(), transformer_add_inequality_with_linear_term(), transformer_apply(), transformer_combine(), transformer_empty_p(), transformer_equality_add(), transformer_identity(), transformer_inequality_add(), transformer_intersection(), transformer_normalize(), transformer_range(), transformer_safe_apply(), transformer_undefined, transformer_undefined_p, VALUE_MONE, VALUE_ONE, VALUE_ZERO, vect_add_elem(), and vect_new().

Referenced by integer_binary_operation_to_transformer(), and pointer_binary_operation_to_transformer().

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

◆ integer_nullary_operation_to_transformer()

static transformer integer_nullary_operation_to_transformer ( entity e   __attribute__(unused),
entity f   __attribute__(unused),
transformer pre   __attribute__(unused),
bool is_internal   __attribute__(unused) 
)
static

FI: this function is no longer useful (11 August 2013)

rand() returns an integer between 0 and RAND_MAX. See Semantics/rand01.c

How do you make sure that RAND_MAX is the same for the analyzed code and for the analyzer?

NL already parse by the function which call him (integer_call_expression_to_transformer) if (ENTITY_RAND_P(f)) { tf = transformer_add_inequality_with_integer_constraint(transformer_identity(), e, 0, true); }

Definition at line 2856 of file expression.c.

2861 {
2862  // eg : getchar and sizeof are nullary_operation
2864  /* rand() returns an integer between 0 and RAND_MAX. See
2865  Semantics/rand01.c
2866 
2867  How do you make sure that RAND_MAX is the same for the analyzed
2868  code and for the analyzer?
2869  */
2870  /* NL already parse by the function which call him (integer_call_expression_to_transformer)
2871  if (ENTITY_RAND_P(f)) {
2872  tf = transformer_add_inequality_with_integer_constraint(transformer_identity(),
2873  e, 0, true);
2874  }
2875  */
2876 
2877  return tf;
2878 }

References transformer_undefined.

Referenced by integer_call_expression_to_transformer().

+ Here is the caller graph for this function:

◆ integer_power_to_transformer()

static transformer integer_power_to_transformer ( entity  e,
expression  arg1,
expression  arg2,
transformer  prec,
bool  is_internal 
)
static

Should be rewritten using expression_to_transformer and expression evaluation as in integer_multiply_to_transformer

pips_assert("Precondition is unused", transformer_undefined_p(pre));

Is arg1 bounded? constant?

Is arg2 bounded? constant?

1 is assigned unless arg1 equals 0... which is neglected

Does not work because unary minus is not seen as part of a constant

The expression value must be greater or equal to arg2 and positive

must be duplicated right now because it will be renamed and checked at the same time by value_mappings_compatible_vector_p()

d is negative and even

d is negative, arg1 cannot be 0, expression value is -1, 0 or 1

0 or 1 is assigned unless arg2 equals 0... which is neglected

e >= d^lb2

e <= d^lb2

the assigned value is positive

The assigned value is 1 or -1

Definition at line 2444 of file expression.c.

2449 {
2451  normalized n1 = NORMALIZE_EXPRESSION(arg1);
2452  normalized n2 = NORMALIZE_EXPRESSION(arg2);
2455 
2456  pips_debug(8, "begin\n");
2457 
2458  /* Should be rewritten using expression_to_transformer and expression
2459  evaluation as in integer_multiply_to_transformer */
2460  /* pips_assert("Precondition is unused", transformer_undefined_p(pre)); */
2461  //pips_assert("Shut up the compiler", pre==pre);
2462  pips_assert("Shut up the compiler", is_internal==is_internal);
2463 
2464  /* Is arg1 bounded? constant? */
2465  bool arg1_is_constant_p = false;
2466  //bool arg1_is_bounded_p = false;
2467  intptr_t lb1, ub1;
2468  if(precondition_minmax_of_expression(arg1, pre, &lb1, &ub1)) {
2469  if(lb1==ub1) {
2470  arg1_is_constant_p = true;
2471  }
2472  }
2473  /* Is arg2 bounded? constant? */
2474  bool arg2_is_constant_p = false;
2475  //bool arg2_is_bounded_p = false;
2476  intptr_t lb2, ub2;
2477  if(precondition_minmax_of_expression(arg2, pre, &lb2, &ub2)) {
2478  if(lb2==ub2) {
2479  arg2_is_constant_p = true;
2480  }
2481  }
2482 
2483  if(arg1_is_constant_p && arg2_is_constant_p) {
2484  int v = (int) exponentiate((Value) lb1, (Value) lb2);
2485  tf = transformer_identity();
2487  }
2488  else if(arg2_is_constant_p && normalized_linear_p(n1)) {
2489  //int d = signed_integer_constant_expression_value(arg2);
2490  int d = (int) lb2;
2491 
2492  if(d%2==0) {
2493 
2494  if(d==0) {
2495  /* 1 is assigned unless arg1 equals 0... which is neglected */
2496  Pvecteur v = vect_new((Variable) e, VALUE_ONE);
2497 
2499  tf = make_transformer(NIL,
2502  }
2503  else if(d>0) {
2504  /* Does not work because unary minus is not seen as part of a constant */
2505  /* The expression value must be greater or equal to arg2 and positive */
2506  /* must be duplicated right now because it will be
2507  renamed and checked at the same time by
2508  value_mappings_compatible_vector_p() */
2509  Pvecteur vlb1 = vect_dup(normalized_linear(n1));
2513 
2514  vect_add_elem(&vlb1, (Variable) e, VALUE_MONE);
2515  vect_add_elem(&vlb2, (Variable) e, VALUE_MONE);
2516  clb1 = contrainte_make(vlb1);
2517  clb2 = contrainte_make(vlb2);
2518  clb1->succ = clb2;
2519  tf = make_transformer(NIL,
2521  }
2522  else {
2523  /* d is negative and even */
2524  Pvecteur vub = vect_new((Variable) e, VALUE_ONE);
2525  Pvecteur vlb = vect_new((Variable) e, VALUE_MONE);
2528 
2529  vect_add_elem(&vub, TCST, VALUE_MONE);
2530  clb = contrainte_make(vlb);
2531  cub = contrainte_make(vub);
2532  clb->succ = cub;
2533  tf = make_transformer(NIL,
2535  }
2536  }
2537  else if(d<0) {
2538  /* d is negative, arg1 cannot be 0, expression value is -1, 0
2539  or 1 */
2540  Pvecteur vub = vect_new((Variable) e, VALUE_MONE);
2541  Pvecteur vlb = vect_new((Variable) e, VALUE_ONE);
2544 
2545  vect_add_elem(&vub, TCST, VALUE_MONE);
2546  vect_add_elem(&vlb, TCST, VALUE_MONE);
2547  clb = contrainte_make(vlb);
2548  cub = contrainte_make(vub);
2549  clb->succ = cub;
2550  tf = make_transformer(NIL,
2552  }
2553  else if(d==1) {
2555 
2556  vect_add_elem(&v, (Variable) e, VALUE_MONE);
2557  tf = make_transformer(NIL,
2560  }
2561  }
2562  else if(arg1_is_constant_p) {
2563  //int d = signed_integer_constant_expression_value(arg1);
2564  int d = (int) lb1;
2565 
2566  if(d==0||d==1) {
2567  /* 0 or 1 is assigned unless arg2 equals 0... which is neglected */
2568  Pvecteur v = vect_new((Variable) e, VALUE_ONE);
2569 
2570  vect_add_elem(&v, TCST, int_to_value(-d));
2571  tf = make_transformer(NIL,
2574  }
2575  else if(d > 1) { // e>=0, always
2576 
2577  tf = transformer_identity();
2578 
2579  /* e >= d^lb2 */
2580  if(lb2>=1) {
2581  Value elb2 = exponentiate((Value) d, (Value) lb2);
2582  tf =
2584  (Variable) e,
2585  (int) elb2,
2586  false);
2587  }
2588 
2589  /* e <= d^lb2 */
2590  if(ub2<INT_MAX) {
2591  // FI: let's hope no overflow is generated...
2592  Value eub2 = exponentiate((Value) d, (Value) ub2);
2593  tf =
2595  (Variable) e,
2596  (int) eub2,
2597  true);
2598  }
2599 
2600 
2601  /* the assigned value is positive */
2602  Pvecteur v1 = vect_new((Variable) e, VALUE_MONE);
2603  //Pcontrainte c1 = contrainte_make(v1);
2604  tf = transformer_inequality_add(tf, v1);
2605 
2606  if(normalized_linear_p(n2)) {
2608  //Pcontrainte c2 = CONTRAINTE_UNDEFINED;
2610  //Pcontrainte c3 = CONTRAINTE_UNDEFINED;
2611 
2612  vect_add_elem(&v2, TCST, VALUE_ONE);
2613  vect_add_elem(&v2, (Variable) e, VALUE_MONE);
2614  tf = transformer_inequality_add(tf, v2);
2615  // c2 = contrainte_make(v2);
2616  //contrainte_succ(c1) = c2;
2617  vect_add_elem(&v3, (Variable) e, VALUE_MONE);
2618  //c3 = contrainte_make(v3);
2619  //contrainte_succ(c2) = c3;
2620  tf = transformer_inequality_add(tf, v3);
2621  }
2622 
2623  //tf = make_transformer(NIL,
2624  // make_predicate(sc_make(CONTRAINTE_UNDEFINED, c1)));
2625 
2626  }
2627  else if(d == -1) {
2628  /* The assigned value is 1 or -1 */
2629  Pvecteur vub = vect_new((Variable) e, VALUE_MONE);
2630  Pvecteur vlb = vect_new((Variable) e, VALUE_ONE);
2633 
2634  vect_add_elem(&vub, TCST, VALUE_MONE);
2635  vect_add_elem(&vlb, TCST, VALUE_MONE);
2636  clb = contrainte_make(vlb);
2637  cub = contrainte_make(vub);
2638  clb->succ = cub;
2639  tf = make_transformer(NIL,
2641  }
2642  }
2643 
2644  free_transformer(pre);
2645 
2646  ifdebug(8) {
2647  pips_debug(8, "result:\n");
2648  dump_transformer(tf);
2649  pips_debug(8, "end\n");
2650  }
2651 
2652  return tf;
2653 }
Value exponentiate(Value, int)
exp.c
Definition: exp.c:45

References contrainte_make(), CONTRAINTE_UNDEFINED, dump_transformer, exponentiate(), free_transformer(), ifdebug, int, int_to_value, intptr_t, make_predicate(), make_transformer(), NIL, NORMALIZE_EXPRESSION, normalized_linear, normalized_linear_p, pips_assert, pips_debug, precondition_minmax_of_expression(), sc_make(), Scontrainte::succ, TCST, transformer_add_equality_with_integer_constant(), transformer_add_inequality_with_integer_constraint(), transformer_identity(), transformer_inequality_add(), transformer_range(), transformer_undefined, transformer_undefined_p, VALUE_MONE, VALUE_ONE, vect_add_elem(), vect_dup(), vect_multiply(), and vect_new().

Referenced by integer_binary_operation_to_transformer().

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

◆ integer_right_shift_to_transformer()

static transformer integer_right_shift_to_transformer ( entity  e,
expression  arg1,
expression  arg2,
transformer  pre,
bool  is_internal 
)
static

More could be done along the line of integer_left_shift_to_transformer()...

when need arises.

pips_assert("Precondition is unused", transformer_undefined_p(pre));

must be duplicated right now because it will be renamed and checked at the same time by value_mappings_compatible_vector_p()

Definition at line 1827 of file expression.c.

1832 {
1834  normalized n1 = NORMALIZE_EXPRESSION(arg1);
1835 
1836  pips_debug(8, "begin with is_internal=%s\n",
1837  bool_to_string(is_internal));
1838 
1839  /* pips_assert("Precondition is unused", transformer_undefined_p(pre)); */
1840  pips_assert("Shut up the compiler", pre==pre);
1841 
1844  int d = integer_constant_expression_value(arg2);
1845  Value val = value_lshift((Value) 1, (Value) d);
1846  /* must be duplicated right now because it will be
1847  renamed and checked at the same time by
1848  value_mappings_compatible_vector_p() */
1849  Pvecteur vlb =
1851  Pvecteur vub = vect_dup(normalized_linear(n1));
1854 
1855  vect_add_elem(&vlb, (Variable) e, val);
1856  vect_add_elem(&vub, (Variable) e, -val);
1857  vect_add_elem(&vub, TCST, VALUE_ONE-val);
1858  clb = contrainte_make(vlb);
1859  cub = contrainte_make(vub);
1860  clb->succ = cub;
1861  tf = make_transformer(NIL,
1863  }
1864 
1865  ifdebug(8) {
1866  pips_debug(8, "result:\n");
1867  dump_transformer(tf);
1868  pips_debug(8, "end\n");
1869  }
1870 
1871  return tf;
1872 }

References bool_to_string(), contrainte_make(), CONTRAINTE_UNDEFINED, dump_transformer, ifdebug, integer_constant_expression_p(), integer_constant_expression_value(), make_predicate(), make_transformer(), NIL, NORMALIZE_EXPRESSION, normalized_linear, normalized_linear_p, pips_assert, pips_debug, sc_make(), Scontrainte::succ, TCST, transformer_undefined, value_lshift, value_mappings_compatible_vector_p(), VALUE_MONE, VALUE_ONE, vect_add_elem(), vect_dup(), and vect_multiply().

Referenced by integer_binary_operation_to_transformer().

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

◆ integer_unary_operation_to_transformer()

static transformer integer_unary_operation_to_transformer ( entity  e,
entity  op,
expression  e1,
transformer  pre,
bool  is_internal 
)
static

Definition at line 2880 of file expression.c.

2885 {
2887 
2888  tf = generic_unary_operation_to_transformer(e, op, e1, pre, is_internal);
2889 
2890  if(transformer_undefined_p(tf)) {
2891  if(ENTITY_IABS_P(op)
2892  || ENTITY_C_ABS_P(op) || ENTITY_LABS_P(op) || ENTITY_LLABS_P(op)) {
2893  tf = iabs_to_transformer(e, e1, pre, is_internal);
2894  }
2895  }
2896 
2897  // if(transformer_undefined_p(tf)) {
2898  // tf = generic_unary_operation_to_transformer(e, op, e1, pre, is_internal);
2899  //}
2900 
2901  return tf;
2902 }
static transformer iabs_to_transformer(entity v, expression expr, transformer pre, bool is_internal)
Definition: expression.c:1693

References ENTITY_C_ABS_P, ENTITY_IABS_P, ENTITY_LABS_P, ENTITY_LLABS_P, generic_unary_operation_to_transformer(), iabs_to_transformer(), transformer_undefined, and transformer_undefined_p.

Referenced by integer_call_expression_to_transformer().

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

◆ lhs_expression_to_transformer()

transformer lhs_expression_to_transformer ( entity  e,
expression  lhs,
transformer  pre 
)

This function deals with e1.e2 and e1->e2, not with simple references such as x or a[i].

This piece of code has mainly been retrieved from any_assign_to_transformer().

FI: I am not sure how to factorize it out because entity e corresponds to some memory location and is modified in an assignement environment. Here, e is likely to be a temporary value. It is not updated. It should not appear among the transformer arguments

Parameters
lhshs
prere

Definition at line 6262 of file expression.c.

6263 {
6264  syntax slhs = expression_syntax(lhs);
6266 
6267  if(syntax_call_p(slhs)) {
6270  int n = (int) gen_length(l);
6271  // FI: I wonder what happens with side effects in the rhs and
6272  // with pointer dereferencing in the rhs
6273  FOREACH(CELL, cp, l) {
6275 
6276  // example of case which is normally filter *p when p formal
6277  // parameter, or dynamic allocation of p
6278  if(semantics_usable_points_to_reference_p(rlhs, lhs, n)) {
6279  if (analyzed_reference_p(rlhs)) {
6281 
6282  if(!entity_undefined_p(ecp)) { // the location is analyzed
6283  // The preconditions may make the convex hull useful when
6284  // different locations have known values or are
6285  // constrained
6286  transformer rt = copy_transformer(pre);
6287  rt = transformer_add_equality(rt, e, ecp);
6288 
6289  // NL : a better way to do this may exit but I don't know it
6290  if (transformer_undefined_p(tf))
6291  tf = rt;
6292  else {
6293  tf = transformer_convex_hull(tf, rt);
6294  free_transformer(rt);
6295  }
6296  }
6297  }
6298  }
6299  }
6300  }
6301  }
6302  else {
6303  // It might be more useful to process the reference for side effects
6304  pips_internal_error("Improper argument.\n");
6305  }
6306  return tf;
6307 }
bool pt_to_list_undefined_p(void)
points_to.c
list semantics_expression_to_points_to_sources(expression e)
Special wrapping for the semantics analyses.
Definition: points_to.c:94
bool analyzed_reference_p(reference)
FI: Nelson explains the motivation for can_be_constant_path_p() but I do not understand them.
Definition: value.c:518

References analyzed_reference_p(), CELL, cell_any_reference(), constant_memory_access_path_to_location_entity(), constant_path_analyzed_p(), copy_transformer(), cp, entity_undefined_p, expression_syntax, FOREACH, free_transformer(), gen_length(), int, pips_internal_error, pt_to_list_undefined_p(), semantics_expression_to_points_to_sources(), semantics_usable_points_to_reference_p(), syntax_call_p, transformer_add_equality(), transformer_convex_hull(), transformer_undefined, and transformer_undefined_p.

Referenced by integer_call_expression_to_transformer().

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

◆ logical_binary_function_to_transformer()

static transformer logical_binary_function_to_transformer ( entity  v,
call  c,
transformer  pre,
bool  is_internal 
)
static

FI: slight signature mismatch: no need to propagate the call once you know it is a binary operator...

Non internal overloaded functions such as EQ, NEQ, GE, GT, LE, LT,...

if the transformer is not feasible, return false

if the transformer is not feasible, return true

general case due to C convention about integers equal to 0 or not.

if v is in [0..1], v can be used as such. else if v>0, return 1 else if v<0, return 1 else 0<=v<=1

Definition at line 3769 of file expression.c.

3773 {
3775  entity op = call_function(c);
3776 
3777  if(ENTITY_AND_P(op)||ENTITY_OR_P(op)||ENTITY_EQUAL_P(op)
3780  tf = logical_binary_operation_to_transformer(v, c, pre, is_internal);
3781  }
3782  else if(ENTITY_ASSIGN_P(op)) {
3783  /* FI: slight signature mismatch: no need to propagate the call
3784  once you know it is a binary operator... */
3785  list args = call_arguments(c);
3786  expression lhs = EXPRESSION(CAR(args));
3787  expression rhs = EXPRESSION(CAR(CDR(args)));
3788  tf = assign_operation_to_transformer(v, lhs, rhs, pre);
3789  }
3790  else if(ENTITY_RELATIONAL_OPERATOR_P(op)) {
3791  expression expr1 = EXPRESSION(CAR(call_arguments(c)));
3792  expression expr2 = EXPRESSION(CAR(CDR(call_arguments(c))));
3793  basic b1 = basic_of_expression(expr1);
3794  basic b2 = basic_of_expression(expr2);
3795 
3797  tf = logical_binary_operation_to_transformer(v, c, pre, is_internal);
3798  }
3799  else if(!transformer_undefined_p(pre)) {
3800  /* Non internal overloaded functions such as EQ, NEQ, GE, GT, LE, LT,... */
3801  //entity tmp = make_local_temporary_value_entity(entity_type(v));
3803  op,
3804  expr1,
3805  expr2,
3806  pre,
3807  true,
3808  true);
3809 
3810  // The normalization of tfe and tfne below is key because
3811  // transformer_empty_p() is quite weak (but fast) [FI: transformer_is_empty_p]
3812  tfe = transformer_normalize(tfe, 2);
3813  /* if the transformer is not feasible, return false */
3814  if(transformer_empty_p(tfe)) {
3816  Pcontrainte c;
3817 
3818  c = contrainte_make(eq);
3819  tf = make_transformer(NIL,
3821  }
3822  else {
3824  op,
3825  expr1,
3826  expr2,
3827  pre,
3828  false,
3829  true);
3830 
3831  tfne = transformer_normalize(tfne, 2);
3832  /* if the transformer is not feasible, return true */
3833  if(transformer_empty_p(tfne)) {
3835  Pcontrainte c;
3836 
3838  c = contrainte_make(eq);
3839  tf = make_transformer(NIL,
3841  }
3842  free_transformer(tfne);
3843  }
3844  free_transformer(tfe);
3845  }
3846  else {
3847  ;
3848  }
3849 
3850  free_basic(b1);
3851  free_basic(b2);
3852  }
3853  else {
3854  /* general case due to C convention about integers equal to 0 or
3855  * not.
3856  *
3857  * if v is in [0..1], v can be used as such.
3858  * else if v>0, return 1
3859  * else if v<0, return 1
3860  * else 0<=v<=1
3861  */
3864  tf = integer_binary_operation_to_transformer(v, op, e1, e2,
3865  pre, is_internal);
3866  if(!transformer_undefined_p(tf)) {
3867  // FI: should we restrict us to the range of tf?
3868  intptr_t vmin, vmax;
3869  bool success = precondition_minmax_of_value(v, tf, &vmin, &vmax);
3870  if(success) {
3871  if(vmin>=0 && vmax<=1)
3872  ; // tf can be returned as such
3873  else if(vmin>=1 || vmax<=-1) {
3874  // Must return v==1
3875  free_transformer(tf);
3876  tf = transformer_identity();
3878  }
3879  }
3880  }
3881 
3882  if(transformer_undefined_p(tf)) {
3883  // Must return 0<=v<=1
3884  tf = transformer_identity();
3887  }
3888  }
3889 
3890  return tf;
3891 }
bool success
Definition: gpips-local.h:59
#define ENTITY_OR_P(e)
#define ENTITY_RELATIONAL_OPERATOR_P(e)
#define ENTITY_AND_P(e)
#define ENTITY_NON_EQUAL_P(e)
#define ENTITY_EQUAL_P(e)
#define ENTITY_BITWISE_OR_P(e)
#define ENTITY_BITWISE_AND_P(e)
Value b2
Definition: sc_gram.c:105
Value b1
booleen indiquant quel membre est en cours d'analyse
Definition: sc_gram.c:105
transformer transformer_add_any_relation_information(transformer pre, entity op, expression e1, expression e2, transformer context, bool veracity, bool upwards)
compute transformer or precondition
Definition: expression.c:4686
static transformer logical_binary_operation_to_transformer(entity v, call c, transformer pre, bool is_internal)
Definition: expression.c:3641

References assign_operation_to_transformer(), b1, b2, basic_logical_p, basic_of_expression(), call_arguments, call_function, CAR, CDR, contrainte_make(), CONTRAINTE_UNDEFINED, copy_transformer(), ENTITY_AND_P, ENTITY_ASSIGN_P, ENTITY_BITWISE_AND_P, ENTITY_BITWISE_OR_P, ENTITY_BITWISE_XOR_P, ENTITY_EQUAL_P, ENTITY_NON_EQUAL_P, ENTITY_OR_P, ENTITY_RELATIONAL_OPERATOR_P, eq, EXPRESSION, free_basic(), free_transformer(), integer_binary_operation_to_transformer(), intptr_t, logical_binary_operation_to_transformer(), make_predicate(), make_transformer(), NIL, precondition_minmax_of_value(), sc_make(), TCST, transformer_add_any_relation_information(), transformer_add_equality_with_integer_constant(), transformer_add_inequality_with_integer_constraint(), transformer_empty_p(), transformer_identity(), transformer_normalize(), transformer_undefined, transformer_undefined_p, VALUE_MONE, VALUE_ONE, vect_add_elem(), and vect_new().

Referenced by logical_intrinsic_to_transformer().

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

◆ logical_binary_operation_to_transformer()

static transformer logical_binary_operation_to_transformer ( entity  v,
call  c,
transformer  pre,
bool  is_internal 
)
static

v <= tmp1, v <= tmp2, v >= tmp1+tmp2-1

v >= tmp1, v>= tmp2, v <= tmp1+tmp2

v >= 1-tmp1-tmp2, v >= tmp1+tmp2-1, i.e. -v -tmp1 -tmp2 + 1 <= 0, -v+tmp1+tmp2-1<=0 v <= 1-tmp1+tmp2, v <= 1+tmp1-tmp2, i.e. v + tmp1 - tmp2 - 1 <= 0, v - tmp1 + tmp2 - 1 <=0

v <= tmp1+tmp2, v <= 2-tmp1-tmp2, i.e. v - tmp 1 - tmp 2 <= 0, v -tmp1-tmp2 -2 <= 0 v >= tmp1 - tmp2, v >= -tmp1+tmp2, i.e. -v + tmp1 - tmp2 <=0, -v - tmp1 + tmp2 <=0

Definition at line 3641 of file expression.c.

3645 {
3646  entity op = call_function(c);
3647  Pvecteur eq1 = VECTEUR_NUL;
3648  Pvecteur eq2 = VECTEUR_NUL;
3649  Pvecteur eq3 = VECTEUR_NUL;
3650  Pvecteur eq4 = VECTEUR_NUL;
3655  transformer tf1 = logical_expression_to_transformer(tmp1, arg1, pre, is_internal);
3656  transformer tf2 = logical_expression_to_transformer(tmp2, arg2, pre, is_internal);
3658 
3659  ifdebug(9) {
3660  pips_debug(9, "Begin for value %s with subtransformers:\n",
3661  entity_name(v));
3662  dump_transformer(tf1);
3663  dump_transformer(tf2);
3664  }
3665 
3666  free_transformer(tf1);
3667  free_transformer(tf2);
3668 
3669  ifdebug(9) {
3670  pips_debug(9, "Union of subtransformers:\n");
3671  dump_transformer(tf);
3672  }
3673 
3674  if(!transformer_undefined_p(tf)) {
3675  if(ENTITY_AND_P(op)) {
3676  /* v <= tmp1, v <= tmp2, v >= tmp1+tmp2-1 */
3677  eq1 = vect_new((Variable) v, VALUE_ONE);
3678  vect_add_elem(&eq1, (Variable) tmp1, VALUE_MONE);
3679  eq2 = vect_new((Variable) v, VALUE_ONE);
3680  vect_add_elem(&eq2, (Variable) tmp2, VALUE_MONE);
3681  eq3 = vect_new((Variable) v, VALUE_MONE);
3682  vect_add_elem(&eq3, (Variable) tmp1, VALUE_ONE);
3683  vect_add_elem(&eq3, (Variable) tmp2, VALUE_ONE);
3684  vect_add_elem(&eq3, TCST, VALUE_MONE);
3685  }
3686  else if(ENTITY_OR_P(op)) {
3687  /* v >= tmp1, v>= tmp2, v <= tmp1+tmp2 */
3688  eq1 = vect_new((Variable) v, VALUE_MONE);
3689  vect_add_elem(&eq1, (Variable) tmp1, VALUE_ONE);
3690  eq2 = vect_new((Variable) v, VALUE_MONE);
3691  vect_add_elem(&eq2, (Variable) tmp2, VALUE_ONE);
3692  eq3 = vect_new((Variable) v, VALUE_ONE);
3693  vect_add_elem(&eq3, (Variable) tmp1, VALUE_MONE);
3694  vect_add_elem(&eq3, (Variable) tmp2, VALUE_MONE);
3695  }
3696  else if(ENTITY_EQUAL_P(op)) {
3697  /* v >= 1-tmp1-tmp2, v >= tmp1+tmp2-1, i.e.
3698  * -v -tmp1 -tmp2 + 1 <= 0, -v+tmp1+tmp2-1<=0
3699  * v <= 1-tmp1+tmp2, v <= 1+tmp1-tmp2, i.e.
3700  * v + tmp1 - tmp2 - 1 <= 0, v - tmp1 + tmp2 - 1 <=0
3701  */
3702  eq1 = vect_new((Variable) v, VALUE_MONE);
3703  vect_add_elem(&eq1, (Variable) tmp1, VALUE_MONE);
3704  vect_add_elem(&eq1, (Variable) tmp2, VALUE_MONE);
3705  vect_add_elem(&eq1, TCST , VALUE_ONE);
3706 
3707  eq2 = vect_new((Variable) v, VALUE_MONE);
3708  vect_add_elem(&eq2, (Variable) tmp1, VALUE_ONE);
3709  vect_add_elem(&eq2, (Variable) tmp2, VALUE_ONE);
3710  vect_add_elem(&eq2, TCST , VALUE_MONE);
3711 
3712  eq3 = vect_new((Variable) v, VALUE_ONE);
3713  vect_add_elem(&eq3, (Variable) tmp1, VALUE_ONE);
3714  vect_add_elem(&eq3, (Variable) tmp2, VALUE_MONE);
3715  vect_add_elem(&eq3, TCST , VALUE_MONE);
3716 
3717  eq4 = vect_new((Variable) v, VALUE_ONE);
3718  vect_add_elem(&eq4, (Variable) tmp1, VALUE_MONE);
3719  vect_add_elem(&eq4, (Variable) tmp2, VALUE_ONE);
3720  vect_add_elem(&eq4, TCST , VALUE_MONE);
3721  }
3722  else if(ENTITY_NON_EQUAL_P(op) || ENTITY_BITWISE_XOR_P(op)) {
3723  /* v <= tmp1+tmp2, v <= 2-tmp1-tmp2, i.e.
3724  * v - tmp 1 - tmp 2 <= 0, v -tmp1-tmp2 -2 <= 0
3725  * v >= tmp1 - tmp2, v >= -tmp1+tmp2, i.e.
3726  * -v + tmp1 - tmp2 <=0, -v - tmp1 + tmp2 <=0
3727  */
3728  eq1 = vect_new((Variable) v, VALUE_ONE);
3729  vect_add_elem(&eq1, (Variable) tmp1, VALUE_MONE);
3730  vect_add_elem(&eq1, (Variable) tmp2, VALUE_MONE);
3731 
3732  eq2 = vect_new((Variable) v, VALUE_ONE);
3733  vect_add_elem(&eq2, (Variable) tmp1, VALUE_ONE);
3734  vect_add_elem(&eq2, (Variable) tmp2, VALUE_ONE);
3736 
3737  eq3 = vect_new((Variable) v, VALUE_MONE);
3738  vect_add_elem(&eq3, (Variable) tmp1, VALUE_ONE);
3739  vect_add_elem(&eq3, (Variable) tmp2, VALUE_MONE);
3740 
3741  eq4 = vect_new((Variable) v, VALUE_MONE);
3742  vect_add_elem(&eq4, (Variable) tmp1, VALUE_MONE);
3743  vect_add_elem(&eq4, (Variable) tmp2, VALUE_ONE);
3744 
3745  }
3746  else {
3747  pips_internal_error("Unexpected binary logical operator %s",
3748  entity_name(op));
3749  }
3750  tf = transformer_inequality_add(tf, eq1);
3751  tf = transformer_inequality_add(tf, eq2);
3752  if(!VECTEUR_NUL_P(eq3)) {
3753  if(!VECTEUR_NUL_P(eq4)) {
3754  tf = transformer_inequality_add(tf, eq4);
3755  }
3756  tf = transformer_inequality_add(tf, eq3);
3757  }
3759  }
3760 
3761  ifdebug(9) {
3762  pips_debug(9, "End with transformer:\n");
3763  dump_transformer(tf);
3764  }
3765 
3766  return tf;
3767 }
transformer transformer_logical_inequalities_add(transformer tf, entity v)
PROCESSING OF LOGICAL EXPRESSIONS.
Definition: expression.c:3569
transformer transformer_safe_intersection(transformer t1, transformer t2)
Allocate a new transformer.
Definition: transformer.c:639
#define VECTEUR_NUL_P(v)

References call_arguments, call_function, CAR, CDR, dump_transformer, ENTITY_AND_P, ENTITY_BITWISE_XOR_P, ENTITY_EQUAL_P, entity_name, ENTITY_NON_EQUAL_P, ENTITY_OR_P, entity_type, EXPRESSION, free_transformer(), ifdebug, logical_expression_to_transformer(), make_local_temporary_value_entity(), pips_debug, pips_internal_error, TCST, transformer_inequality_add(), transformer_logical_inequalities_add(), transformer_safe_intersection(), transformer_undefined_p, VALUE_MONE, VALUE_ONE, vect_add_elem(), vect_new(), VECTEUR_NUL, and VECTEUR_NUL_P.

Referenced by logical_binary_function_to_transformer().

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

◆ logical_constant_to_transformer()

static transformer logical_constant_to_transformer ( entity  v,
entity  f 
)
static

Definition at line 3583 of file expression.c.

3585 {
3588  Pcontrainte c;
3589 
3590  if(ENTITY_TRUE_P(f) || ENTITY_ONE_P(f)) {
3592  }
3593  else if(ENTITY_FALSE_P(f) || ENTITY_ZERO_P(f)) {
3594  ;
3595  }
3596  else {
3597  pips_internal_error("Unknown logical constant %s",
3598  entity_name(f));
3599  }
3600  c = contrainte_make(eq);
3601  tf = make_transformer(NIL,
3603 
3604  return tf;
3605 }
#define ENTITY_TRUE_P(e)
#define ENTITY_ONE_P(e)
#define ENTITY_FALSE_P(e)
#define ENTITY_ZERO_P(e)

References contrainte_make(), CONTRAINTE_UNDEFINED, ENTITY_FALSE_P, entity_name, ENTITY_ONE_P, ENTITY_TRUE_P, ENTITY_ZERO_P, eq, f(), make_predicate(), make_transformer(), NIL, pips_internal_error, sc_make(), TCST, transformer_undefined, VALUE_MONE, VALUE_ONE, vect_add_elem(), and vect_new().

Referenced by logical_intrinsic_to_transformer().

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

◆ logical_expression_to_transformer()

transformer logical_expression_to_transformer ( entity  v,
expression  rhs,
transformer  pre,
bool  is_internal 
)

Could be used to compute preconditions too.

v is assumed to be a new value or a temporary value.

Is likely to be handled as a nullary intrinsics

Parameters
rhshs
prere
is_internals_internal

Definition at line 3938 of file expression.c.

3942 {
3944  syntax srhs = expression_syntax(rhs);
3945 
3946  switch(syntax_tag(srhs)) {
3947  case is_syntax_call: {
3948  call c = syntax_call(srhs);
3949  entity f = call_function(c);
3950  if(intrinsic_entity_p(f))
3951  tf = logical_intrinsic_to_transformer(v, c, pre, is_internal);
3952  else if(call_constant_p(c)) {
3953  entity cf = call_function(c);
3954  int i;
3955  if(logical_constant_p(cf)) {
3956  /* Is likely to be handled as a nullary intrinsics */
3957  tf = logical_intrinsic_to_transformer(v, c, pre, is_internal);
3958  }
3959  else if(integer_constant_p(cf, &i)) {
3960  if(i!=0)
3961  i = 1;
3962  tf = transformer_identity();
3964  }
3965  else
3966  pips_internal_error("Unexpected case.\n");
3967  }
3968  else {
3969  // call to a C or Fortran bool function
3970  //list ef = expression_to_proper_effects(rhs);
3971  tf = user_function_call_to_transformer(v, rhs, pre);
3972  }
3973  break;
3974  }
3975  case is_syntax_reference: {
3976  // FI: information in precondition pre is lost here
3978  is_internal);
3980  // FI: let us assume that pre is a range, not a transformer
3981  tf = transformer_intersection(rtf, pre);
3982  }
3983  break;
3984  }
3985  case is_syntax_range:
3986  pips_internal_error("Unexpected tag %d", syntax_tag(srhs));
3987  break;
3988  default:
3989  pips_internal_error("Illegal tag %d", syntax_tag(srhs));
3990  }
3991  return tf;
3992 }
bool logical_constant_p(entity ent)
Definition: constant.c:463
bool intrinsic_entity_p(entity e)
Definition: entity.c:1272
bool call_constant_p(call c)
bool call_constant_p(call c): Returns true if "c" is a call to a constant, that is,...
Definition: expression.c:1965
static transformer logical_reference_to_transformer(entity v, entity r, bool is_internal)
v is assumed to be a temporary value and r a logical program variable
Definition: expression.c:3894
transformer logical_intrinsic_to_transformer(entity v, call c, transformer pre, bool is_internal)
Definition: expression.c:3911

References call_constant_p(), call_function, expression_syntax, f(), integer_constant_p(), intrinsic_entity_p(), is_syntax_call, is_syntax_range, is_syntax_reference, logical_constant_p(), logical_intrinsic_to_transformer(), logical_reference_to_transformer(), pips_internal_error, reference_variable, syntax_call, syntax_reference, syntax_tag, transformer_add_equality_with_integer_constant(), transformer_identity(), transformer_intersection(), transformer_undefined, transformer_undefined_p, and user_function_call_to_transformer().

Referenced by any_expression_to_transformer(), logical_binary_operation_to_transformer(), and logical_unary_operation_to_transformer().

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

◆ logical_intrinsic_to_transformer()

transformer logical_intrinsic_to_transformer ( entity  v,
call  c,
transformer  pre,
bool  is_internal 
)
Parameters
prere
is_internals_internal

Definition at line 3911 of file expression.c.

3915 {
3917 
3918  switch(gen_length(call_arguments(c))) {
3919  case 0:
3921  break;
3922  case 1:
3923  tf = logical_unary_operation_to_transformer(v, c, pre, is_internal);
3924  break;
3925  case 2:
3926  tf = logical_binary_function_to_transformer(v, c, pre, is_internal);
3927  break;
3928  default:
3929  pips_internal_error("Too many logical arguments, %d, for operator %s",
3932  }
3933  return tf;
3934 }
static transformer logical_binary_function_to_transformer(entity v, call c, transformer pre, bool is_internal)
Definition: expression.c:3769
static transformer logical_unary_operation_to_transformer(entity v, call c, transformer pre, bool is_internal)
Definition: expression.c:3607
static transformer logical_constant_to_transformer(entity v, entity f)
Definition: expression.c:3583

References call_arguments, call_function, entity_name, gen_length(), logical_binary_function_to_transformer(), logical_constant_to_transformer(), logical_unary_operation_to_transformer(), pips_internal_error, and transformer_undefined.

Referenced by logical_expression_to_transformer().

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

◆ logical_not_to_transformer()

transformer logical_not_to_transformer ( entity  v,
list  args,
transformer  pre 
)

returns the transformer associated to a C logical not, !, applied to an integer argument, when meaningful, and transformer_undefined otherwise.

Effects must be used at a higher level to fall back on a legal transformer.

Parameters
vis the value associated to the expression
argsis assumed to have only one expression element of type int or enum negated by !
preis the current precondition
Parameters
argsrgs
prere

Definition at line 5571 of file expression.c.

5574 {
5575  expression le = EXPRESSION(CAR(args));
5576  //basic be = basic_of_expression(le);
5578 
5579  //if(basic_int_p(be)) {
5581  tf = safe_any_expression_to_transformer(tmp_v, le, pre, true);
5582  transformer tfr = transformer_range(tf);
5583  intptr_t lb, ub;
5584 
5585  if(precondition_minmax_of_value(tmp_v, tfr, &lb, &ub)) {
5586  if(lb==ub && lb==0)
5588  else if(lb>0 || ub<0)
5590  else {
5593  }
5594  }
5595  else {
5598  }
5599  free_transformer(tfr);
5600  // }
5601 
5602  //free_basic(be);
5603 
5604  return tf;
5605 }

References CAR, EXPRESSION, free_transformer(), intptr_t, make_local_temporary_integer_value_entity(), precondition_minmax_of_value(), safe_any_expression_to_transformer(), transformer_add_equality_with_integer_constant(), transformer_add_inequality_with_integer_constraint(), transformer_range(), and transformer_undefined.

Referenced by integer_call_expression_to_transformer().

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

◆ logical_reference_to_transformer()

static transformer logical_reference_to_transformer ( entity  v,
entity  r,
bool  is_internal 
)
static

v is assumed to be a temporary value and r a logical program variable

Definition at line 3894 of file expression.c.

3897 {
3899 
3900  if(!is_internal || entity_has_values_p(r)) {
3901  entity r_new = is_internal? entity_to_new_value(r) : external_entity_to_new_value(r);
3902 
3903 
3904  tf = simple_equality_to_transformer(v, r_new, false);
3905  tf = transformer_logical_inequalities_add(tf, r_new);
3906  }
3907 
3908  return tf;
3909 }

References entity_has_values_p(), entity_to_new_value(), external_entity_to_new_value(), simple_equality_to_transformer(), transformer_logical_inequalities_add(), and transformer_undefined.

Referenced by logical_expression_to_transformer().

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

◆ logical_unary_operation_to_transformer()

static transformer logical_unary_operation_to_transformer ( entity  v,
call  c,
transformer  pre,
bool  is_internal 
)
static

pips_assert("A unique argument", ENDP(CDR(call_arguments(c))));

Definition at line 3607 of file expression.c.

3611 {
3613  entity op = call_function(c);
3616 
3617  /* pips_assert("A unique argument", ENDP(CDR(call_arguments(c)))); */
3618 
3619  if(ENTITY_NOT_P(op)) {
3621  tf = logical_expression_to_transformer(tmp, arg, pre, is_internal);
3622  vect_add_elem(&eq, (Variable) tmp , VALUE_ONE);
3624  }
3625  else {
3626 // pips_internal_error("Unknown logical constant %s",
3627 // entity_name(op));
3628  }
3629  tf = transformer_equality_add(tf, eq);
3631 
3632  if(transformer_undefined_p(tf)) {
3633  semantics_user_warning("Not tested for logical.\n");
3634  //tf = points_to_unary_operation_to_transformer(v, op, arg, pre, is_internal, false);
3635  tf = generic_unary_operation_to_transformer(v, op, arg, pre, is_internal);
3636  }
3637 
3638  return tf;
3639 }

References call_arguments, call_function, CAR, ENTITY_NOT_P, entity_type, eq, EXPRESSION, generic_unary_operation_to_transformer(), logical_expression_to_transformer(), make_local_temporary_value_entity(), semantics_user_warning, TCST, transformer_equality_add(), transformer_logical_inequalities_add(), transformer_undefined, transformer_undefined_p, VALUE_MONE, VALUE_ONE, vect_add_elem(), and vect_new().

Referenced by logical_intrinsic_to_transformer().

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

◆ max0_to_transformer()

static transformer max0_to_transformer ( entity  e,
list  args,
transformer  pre,
bool  is_internal 
)
static

Definition at line 2728 of file expression.c.

2732 {
2733  return integer_minmax_to_transformer(e, args, pre, false, is_internal);
2734 }
static transformer integer_minmax_to_transformer(entity v, list args, transformer pre, bool is_min, bool is_internal)
Definition: expression.c:2655

References integer_minmax_to_transformer().

Referenced by integer_call_expression_to_transformer(), and pointer_call_expression_to_transformer().

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

◆ min0_to_transformer()

static transformer min0_to_transformer ( entity  e,
list  args,
transformer  pre,
bool  is_internal 
)
static

Definition at line 2720 of file expression.c.

2724 {
2725  return integer_minmax_to_transformer(e, args, pre, true, is_internal);
2726 }

References integer_minmax_to_transformer().

Referenced by integer_call_expression_to_transformer(), and pointer_call_expression_to_transformer().

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

◆ modulo_by_a_constant_to_transformer()

transformer modulo_by_a_constant_to_transformer ( entity  v1,
transformer  prec,
entity  v2,
int  k 
)

Analyze v2 % k, with v2 constrainted by tf, assuming tf is a precondition.

See if exist a set v_i such that v2 = sum_i a_i v_i + c. Then v2 can be rewritten as v2 = gcd_i(a_i) lambda + c.

if k divides gcd(a_i) then v2>0 ? v1 = v2 % k = c % k : v1 = v2 % k = ck-k

If the sign of v2 is unknown, ck-k<=v1<=ck

Parameters
v11
precrec
v22

Definition at line 1481 of file expression.c.

1482 {
1484  Value gcd, c, K = (Value) k;
1485 
1486  // exists lambda s.t. v2 = lambda gcd + c ^ 0<=c<gcd
1487  if(transformer_to_1D_lattice(v2, prec, &gcd, &c)) {
1488 
1489  // The sign of gcd does not matter more than the sign of lambda
1490  if(gcd<0) gcd = -gcd;
1491 
1492  // Is v2's sign known ?
1493  // Adding the sign constraint and using LP might be more efficient
1494  bool is_positive_p = false;
1495  bool is_negative_p = false;
1496  intptr_t imin = 0, imax = 0;
1497 
1498  if (precondition_minmax_of_value(v2, prec, &imin, &imax)) {
1499  is_positive_p = imin>=0;
1500  is_negative_p = imax<=0;
1501  }
1502 
1503  if (imin==imax) {
1504  // This piece of code should be useless because we expect
1505  // gcd = 0 and c = imin = imax in such a case
1506  // But it fails with Semantics-New/modulo16.c
1507  mtf = transformer_add_equality_with_integer_constant(mtf, v1, imin%K);
1508  }
1509  else if (gcd!=0) {
1510  if(gcd%k==0) {
1511  if(is_positive_p)
1513  else if(is_negative_p)
1514  mtf = transformer_add_equality_with_integer_constant(mtf, v1, c%K-K);
1515  else {
1516  mtf = transformer_add_inequality_with_integer_constraint(mtf, v1, c%K, true);
1517  mtf = transformer_add_inequality_with_integer_constraint(mtf, v1, c%K-K, false);
1518  }
1519  }
1520  else {
1521  if(is_positive_p) {
1522  mtf = transformer_add_inequality_with_integer_constraint(mtf, v1, K-1, true);
1523  mtf = transformer_add_inequality_with_integer_constraint(mtf, v1, 0, false);
1524  }
1525  else if(is_negative_p) {
1527  mtf = transformer_add_inequality_with_integer_constraint(mtf, v1, -K+1, false);
1528  }
1529  else {
1530  mtf = transformer_add_inequality_with_integer_constraint(mtf, v1, K-1, true);
1531  mtf = transformer_add_inequality_with_integer_constraint(mtf, v1, -K+1, false);
1532  }
1533  }
1534  }
1535  else { // Same result
1536  // v2 = c
1537  if(is_positive_p)
1539  else if(is_negative_p)
1540  mtf = transformer_add_equality_with_integer_constant(mtf, v1, c%K-K);
1541  else {
1542  mtf = transformer_add_inequality_with_integer_constraint(mtf, v1, c%K, true);
1543  mtf = transformer_add_inequality_with_integer_constraint(mtf, v1, c%K-K, false);
1544  }
1545  }
1546  }
1547  else {
1548  // There is no solution. E.g. v2==2 ^ v2==1 or 0==1
1549  // This case should be detected earlier and this piece of code is
1550  // probably unreachable
1551  mtf = empty_transformer(mtf);
1552  }
1553  return mtf;
1554 }
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_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,...
Definition: transformer.c:2480

References empty_transformer(), intptr_t, precondition_minmax_of_value(), transformer_add_equality_with_integer_constant(), transformer_add_inequality_with_integer_constraint(), transformer_identity(), and transformer_to_1D_lattice().

Referenced by modulo_to_transformer().

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

◆ modulo_of_a_constant_to_transformer()

static transformer modulo_of_a_constant_to_transformer ( entity  e,
int  lb1,
int  lb2,
int  ub2 
)
static

Since arg1 is a constant, ub1=lb1

The first argument is numerically known

r == 0 not matter what

A floating point exception is going to be raised

The result is known: r = lb1 % lb2 if lb2!=0

The second argument is negative: lb1>0? r>=0, r<= ub1, r<=-lb2-1 : r<=0, -ub1<=r, r>= lb2+1

the modulo has no impact r=ub1=lb1

r>=0, r<= ub1, r<=-lb2-1

the modulo has no impact r=ub1=lb1

r<=0, -ub1<=r, r>= lb2+1

The second argument is positive: lb1>0? r>=0, r<= ub1, r<=ub2-1 : r<=0, -ub1<=r, -ub2+1<=r

the modulo has no impact r=ub1=lb1

r>=0, r<= ub1, r<=-lb2-1

r>=0, r<= ub1, r<=ub2-1

the modulo has no impact r=ub1=lb1

r<=0, -ub1<=r, -ub2+1<=r

no information is available on the second argument: the sign of the first argument is preserved

Definition at line 1278 of file expression.c.

1279 {
1280  /* Since arg1 is a constant, ub1=lb1 */
1282 
1283  /* The first argument is numerically known */
1284  if(lb1==0) {
1285  /* r == 0 not matter what */
1287  }
1288  else if(lb2==ub2) {
1289  if(lb2==0) {
1290  /* A floating point exception is going to be raised */
1291  semantics_user_warning("Zero divide encountered\n");
1292  tf3 = transformer_empty();
1293  }
1294  else {
1295  /* The result is known: r = lb1 % lb2 if lb2!=0 */
1296  int r = lb1 % lb2;
1298  }
1299  }
1300  else if(ub2<0) {
1301  /* The second argument is negative:
1302  * lb1>0? r>=0, r<= ub1, r<=-lb2-1
1303  * : r<=0, -ub1<=r, r>= lb2+1 */
1304  if(lb1>0) {
1305  if(lb1<-ub2) {
1306  /* the modulo has no impact r=ub1=lb1 */
1308  }
1309  else {
1310  /* r>=0, r<= ub1, r<=-lb2-1 */
1312  e, 0, false);
1313  tf3 = transformer_add_inequality_with_integer_constraint(tf3, e, lb1, true);
1314  tf3 = transformer_add_inequality_with_integer_constraint(tf3, e, -lb2-1, true);
1315  }
1316  }
1317  else {
1318  if(lb1>ub2) {
1319  /* the modulo has no impact r=ub1=lb1 */
1321  }
1322  else {
1323  /* r<=0, -ub1<=r, r>= lb2+1 */
1325  e, 0, true);
1326  tf3 = transformer_add_inequality_with_integer_constraint(tf3, e, lb1, false);
1327  tf3 = transformer_add_inequality_with_integer_constraint(tf3, e, lb2+1, false);
1328  }
1329  }
1330  }
1331  else if(lb2>0) {
1332  /* The second argument is positive:
1333  * lb1>0? r>=0, r<= ub1, r<=ub2-1
1334  * : r<=0, -ub1<=r, -ub2+1<=r
1335  */
1336  if(lb1>0) {
1337  if(lb1<lb2) {
1338  /* the modulo has no impact r=ub1=lb1 */
1340  }
1341  else {
1342  /* r>=0, r<= ub1, r<=-lb2-1 */
1343  /* r>=0, r<= ub1, r<=ub2-1 */
1345  e, 0, false);
1346  tf3 = transformer_add_inequality_with_integer_constraint(tf3, e, lb1, true);
1347  tf3 = transformer_add_inequality_with_integer_constraint(tf3, e, ub2-1, true);
1348  }
1349  }
1350  else {
1351  if(-lb1<ub2) {
1352  /* the modulo has no impact r=ub1=lb1 */
1354  }
1355  else {
1356  /* r<=0, -ub1<=r, -ub2+1<=r */
1358  e, 0, true);
1359  tf3 = transformer_add_inequality_with_integer_constraint(tf3, e, lb1, false);
1360  tf3 = transformer_add_inequality_with_integer_constraint(tf3, e, -ub2+1, false);
1361  }
1362  }
1363  }
1364  else {
1365  /* no information is available on the second argument: the
1366  sign of the first argument is preserved */
1368  e, 0, lb1<0);
1369  }
1370  return tf3;
1371 }

References semantics_user_warning, transformer_add_equality_with_integer_constant(), transformer_add_inequality_with_integer_constraint(), transformer_empty(), transformer_identity(), and transformer_undefined.

Referenced by modulo_to_transformer().

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

◆ modulo_of_a_negative_value_to_transformer()

static transformer modulo_of_a_negative_value_to_transformer ( entity  e,
int  lb1,
int  ub1,
int  lb2,
int  ub2 
)
static

e = [lb1,ub1] % [lb2,ub2] with ub1<=0

arg1 is negative, hence r is always negative: r<=0

the modulo is the identity: lb1<=r<=ub1

arg2 is negative: r>=arg2, r>= lb2+1

the modulo is the identity: lb1<=r<=ub1

arg2 is positive: r<=-arg2+1, r<= -lb2+1

No information is available on arg2: r<=0

Definition at line 1374 of file expression.c.

1377 {
1379  /* arg1 is negative, hence r is always negative: r<=0 */
1380  if(ub2<0) {
1381  if(ub2<lb1) {
1382  /* the modulo is the identity: lb1<=r<=ub1*/
1384  e, lb1, false);
1386  e, ub1, true);
1387  }
1388  else {
1389  /* arg2 is negative: r>=arg2, r>= lb2+1 */
1391  e, 0, true);
1393  e, lb2+1, false);
1394  }
1395  }
1396  else if(lb2>0) {
1397  if(lb2>-ub1) {
1398  /* the modulo is the identity: lb1<=r<=ub1 */
1399  if(lb1>INT_MIN)
1401  e, lb1, false);
1402  else
1403  tf3 = transformer_identity();
1405  e, ub1, true);
1406  }
1407  else {
1408  /* arg2 is positive: r<=-arg2+1, r<= -lb2+1 */
1410  e, 0, true);
1412  e, -lb2+1, true);
1413  }
1414  }
1415  else {
1416  /* No information is available on arg2: r<=0 */
1418  e, 0, true);
1419  }
1420 
1421  return tf3;
1422 }

References transformer_add_inequality_with_integer_constraint(), transformer_identity(), and transformer_undefined.

Referenced by modulo_to_transformer().

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

◆ modulo_of_a_positive_value_to_transformer()

static transformer modulo_of_a_positive_value_to_transformer ( entity  e,
int  lb1,
int  ub1,
int  lb2,
int  ub2 
)
static

arg1 is positive, hence r is always positive: r>=0

the modulo is the identity: lb1<=r<=ub1

arg2 is negative: 0<=r<=-arg2+1, 0<=r<= -ub2+1

the modulo is the identity: lb1<=r<=ub1

arg2 is positive: 0<=r<=arg2-1, 0<=r<= ub2-1

No information is available on arg2: r>=0

Definition at line 1424 of file expression.c.

1427 {
1429  /* arg1 is positive, hence r is always positive: r>=0 */
1430  if(ub2<0) {
1431  if(-ub2>ub1) {
1432  /* the modulo is the identity: lb1<=r<=ub1 */
1434  e, lb1, false);
1436  e, ub1, true);
1437  }
1438  else {
1439  /* arg2 is negative: 0<=r<=-arg2+1, 0<=r<= -ub2+1 */
1441  e, 0, false);
1443  e, -ub2+1, true);
1444  }
1445  }
1446  else if(lb2>0) {
1447  if(lb2>ub1) {
1448  /* the modulo is the identity: lb1<=r<=ub1*/
1450  e, lb1, false);
1452  e, ub1, true);
1453  }
1454  else {
1455  /* arg2 is positive: 0<=r<=arg2-1, 0<=r<= ub2-1 */
1457  e, 0, false);
1459  e, ub2-1, true);
1460  }
1461  }
1462  else {
1463  /* No information is available on arg2: r>=0 */
1465  e, 0, false);
1466  }
1467 
1468  return tf3;
1469 }

References transformer_add_inequality_with_integer_constraint(), transformer_identity(), and transformer_undefined.

Referenced by modulo_to_transformer().

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

◆ modulo_to_transformer()

static transformer modulo_to_transformer ( entity  e,
expression  arg1,
expression  arg2,
transformer  pre,
bool is_internal   __attribute__(unused) 
)
static

Modulo and integer division.

Apparently identical in both C and Fortran

      C    Fortran

a b mod div mod div 3 2 1 1 1 -3 2 -1 -1 -1 3 -2 1 -1 1 -3 -2 -1 1 -1

FI: only implemented for positive dividends. Same for integer division, I believe. Side effects are probably ignored.

FI: to be improved by using expression_to_transformer() and the precondition pre.

FI: to be improved by using the lattice information in the equations of the precondition.

matrice_hermite()

sc_to_matrices()

cut-and-pasted and adapted from multiply_to_transformer(); also useful for divide; the side effects of the two arguments and the derivation of the preconditions and the computation of the numerical bounds should be factorized in one function.

Let's get rid of the exception case right away

A floating point exception is going to be raised

No sign information available about arg1

arg2 is positive: -ub2+1<=r<=ub2-1

arg2 is negative: lb2+1<=r<=-lb2-1

Might be as good to leave it undefined... for the time being. Information about either arg1 or arg2 could be used

Take care of side effects: tf = tf1 o tf2 o tf3

Parameters
arg1assumed to be an integer value
__attribute__not used yet

Definition at line 1580 of file expression.c.

1585 {
1588  transformer tf1 = safe_any_expression_to_transformer(v1, arg1, pre, true);
1589  transformer npre =
1591  transformer pre2 = transformer_range(npre);
1593  transformer tf2 = safe_any_expression_to_transformer(v2, arg2, pre2, true);
1594  npre = transformer_apply(tf2, pre2);
1595  transformer pre3 = transformer_range(npre);
1596  // To be cleaned up later
1597  //transformer tf3 = transformer_undefined;
1599 
1600  pips_debug(8, "begin with pre=%p\n", pre);
1601 
1602  /* cut-and-pasted and adapted from multiply_to_transformer(); also useful for
1603  divide; the side effects of the two arguments and the derivation
1604  of the preconditions and the computation of the numerical bounds
1605  should be factorized in one function. */
1606  if(!transformer_undefined_p(pre) && !transformer_undefined_p(npre)) {
1607  int lb1 = 0;
1608  int ub1 = 0;
1609  int lb2 = 0;
1610  int ub2 = 0;
1611  expression ev1 = entity_to_expression(v1);
1612  expression ev2 = entity_to_expression(v2);
1613 
1614  expression_and_precondition_to_integer_interval(ev1, pre2, &lb1, &ub1);
1615  expression_and_precondition_to_integer_interval(ev2, pre3, &lb2, &ub2);
1616  free_expression(ev1);
1617  free_expression(ev2);
1618 
1619  if(lb2==ub2) {
1620  if(ub2==0) {
1621  /* Let's get rid of the exception case right away */
1622  /* A floating point exception is going to be raised */
1623  semantics_user_warning("Zero divide encountered\n");
1624  tf3 = transformer_empty();
1625  }
1626  else {
1627  // lb2==ub2!=0
1628  // FI: we might have to impose lb2>0
1629  // FI: let's assume that pre is carried by tf1
1630  tf3 = modulo_by_a_constant_to_transformer(e, tf1, v1, lb2);
1631  }
1632  }
1633 
1634  if(transformer_identity_p(tf3)) {
1635  free_transformer(tf3);
1636  if(lb1==ub1) {
1637  tf3 = modulo_of_a_constant_to_transformer(e, lb1, lb2, ub2);
1638  }
1639  else if(ub1<=0) {
1640  tf3 = modulo_of_a_negative_value_to_transformer(e, lb1, ub1, lb2, ub2);
1641  }
1642  else if(lb1>=0) {
1643  tf3 = modulo_of_a_positive_value_to_transformer(e, lb1, ub1, lb2, ub2);
1644  }
1645  else {
1646  /* No sign information available about arg1 */
1647  if(lb2>0) {
1648  /* arg2 is positive: -ub2+1<=r<=ub2-1 */
1650  e, -ub2+1, false);
1652  e, ub2-1, true);
1653  }
1654  else if(ub2<0) {
1655  /* arg2 is negative: lb2+1<=r<=-lb2-1 */
1657  e, lb2+1, false);
1659  e, -lb2-1, true);
1660  }
1661  else
1662  tf3 = transformer_identity();
1663  }
1664  }
1665  }
1666  else {
1667  /* Might be as good to leave it undefined... for the time
1668  being. Information about either arg1 or arg2 could be used */
1669  tf3 = transformer_identity();
1670  ;
1671  }
1672 
1673 
1674  /* Take care of side effects: tf = tf1 o tf2 o tf3 */
1675  tf = transformer_combine(tf1, tf2);
1676  tf = transformer_combine(tf, tf3);
1677  free_transformer(tf2);
1678  free_transformer(tf3);
1679 
1680  free_transformer(pre2);
1681  free_transformer(pre3);
1682  free_transformer(npre);
1683 
1684  ifdebug(8) {
1685  pips_debug(8, "result:\n");
1686  dump_transformer(tf);
1687  pips_debug(8, "end\n");
1688  }
1689 
1690  return tf;
1691 }
bool transformer_identity_p(transformer t)
Check that t is an identity function.
Definition: basic.c:154
static transformer modulo_of_a_positive_value_to_transformer(entity e, int lb1, int ub1, int lb2, int ub2)
Definition: expression.c:1424
static transformer modulo_of_a_constant_to_transformer(entity e, int lb1, int lb2, int ub2)
Definition: expression.c:1278
static transformer modulo_of_a_negative_value_to_transformer(entity e, int lb1, int ub1, int lb2, int ub2)
e = [lb1,ub1] % [lb2,ub2] with ub1<=0
Definition: expression.c:1374
transformer modulo_by_a_constant_to_transformer(entity v1, transformer prec, entity v2, int k)
Analyze v2 % k, with v2 constrainted by tf, assuming tf is a precondition.
Definition: expression.c:1481
void expression_and_precondition_to_integer_interval(expression, transformer, int *, int *)
Evaluate expression e in context p, assuming that e is an integer expression.
Definition: utils.c:325

References dump_transformer, entity_to_expression(), expression_and_precondition_to_integer_interval(), free_expression(), free_transformer(), ifdebug, make_local_temporary_integer_value_entity(), modulo_by_a_constant_to_transformer(), modulo_of_a_constant_to_transformer(), modulo_of_a_negative_value_to_transformer(), modulo_of_a_positive_value_to_transformer(), pips_debug, safe_any_expression_to_transformer(), semantics_user_warning, transformer_add_inequality_with_integer_constraint(), transformer_apply(), transformer_combine(), transformer_empty(), transformer_identity(), transformer_identity_p(), transformer_range(), transformer_undefined, and transformer_undefined_p.

Referenced by integer_binary_operation_to_transformer(), and integer_call_expression_to_transformer().

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

◆ pointer_binary_operation_to_transformer()

static transformer pointer_binary_operation_to_transformer ( entity  e,
expression  expr,
transformer  pre,
bool  is_internal 
)
static

Definition at line 4415 of file expression.c.

4420 {
4421  syntax sexpr = expression_syntax(expr);
4422  call c = syntax_call(sexpr);
4423  entity op = call_function(c);
4424  list args = call_arguments(c);
4425  expression e1 = EXPRESSION(CAR(args));
4426  expression e2 = EXPRESSION(CAR(CDR(args)));
4428 
4429  pips_debug(8, "Begin\n");
4430 
4431  if(ENTITY_PLUS_P(op) || ENTITY_MINUS_P(op)) {
4432  // can occur for arithmetic for pointer
4433  // e1+e2 or e1-e2, e1 and e2 not pointer
4434  tf = addition_operation_to_transformer(e, e1, e2, pre,
4435  ENTITY_PLUS_P(op),
4436  is_internal);
4437  }
4438  if(ENTITY_PLUS_C_P(op)) {
4439  // can occur for arithmetic for pointer
4440  // e1+e2, e1 or e2 pointer
4442  tf = transformer_empty();
4443  pips_user_error("Try to make arithmetic with NULL pointer : %s\n", expression_to_string(expr));
4444  }
4445  else {
4446  tf = addition_operation_to_transformer(e, e1, e2, pre,
4447  ENTITY_PLUS_C_P(op),
4448  is_internal);
4449  }
4450  }
4451  if(ENTITY_MINUS_C_P(op)) {
4452  // can occur for arithmetic for pointer
4453  // e1+e2, e1 or/and e2 pointer
4455  tf = transformer_empty();
4456  pips_user_error("Try to make arithmetic with NULL pointer : %s\n", expression_to_string(expr));
4457  }
4458  else {
4459  tf = addition_operation_to_transformer(e, e1, e2, pre,
4460  ENTITY_PLUS_C_P(op),
4461  is_internal);
4462  }
4463  }
4464  else if(ENTITY_MULTIPLY_P(op)) {
4465  // can occur for arithmetic for pointer
4466  // already multiply by the sizeof
4467  pips_debug(9, "ENTITY_MULTIPLY_P\n");
4469  tf = integer_multiply_to_transformer(e, e1, e2, pre, is_internal);
4470  pips_user_error("can't compute when sizeof already present in arithmetic yet : %s\n", expression_to_string(expr));
4471  }
4472  else {
4473  // compute the multiply with sizeof
4474  tf = expression_multiply_sizeof_to_transformer(e, expr, pre, is_internal);
4475  }
4476  }
4477  else if(ENTITY_PLUS_UPDATE_P(op) || ENTITY_MINUS_UPDATE_P(op)) {
4478  pips_user_error("UPDATE for rhs pointer not done yet : %s\n", expression_to_string(expr));
4479  //tf = update_operation_to_transformer(e, op, e1, e2, pre, is_internal);
4480  }
4481  else if(ENTITY_ASSIGN_P(op)) {
4482  semantics_user_warning("ASSIGN for rhs pointer not tested : %s\n", expression_to_string(expr));
4483  // Maybe need to be redesign like any_assign_to_transformer or assign_rhs_to_reflhs_to_transformer
4484  tf = assign_operation_to_transformer(e, e1, e2, pre);
4485  }
4486  else {
4487  semantics_user_warning("Operator %s not analyzed\n", entity_name(op));
4488  }
4489 
4490  pips_debug(8, "End with tf=%p\n", tf);
4491 
4492  return tf;
4493 }
static transformer expression_multiply_sizeof_to_transformer(entity v, expression e1, transformer prec, bool is_internal)
cut-and-pasted and adapted from multiply_to_transformer();
Definition: expression.c:2169

References addition_operation_to_transformer(), assign_operation_to_transformer(), call_arguments, call_function, CAR, CDR, ENTITY_ASSIGN_P, ENTITY_MINUS_C_P, ENTITY_MINUS_P, ENTITY_MINUS_UPDATE_P, ENTITY_MULTIPLY_P, entity_name, ENTITY_PLUS_C_P, ENTITY_PLUS_P, ENTITY_PLUS_UPDATE_P, EXPRESSION, expression_multiply_sizeof_to_transformer(), expression_syntax, expression_to_string(), have_null_value_in_pointer_expression_p(), have_sizeof_value_in_multiply_pointer_expression_p(), integer_multiply_to_transformer(), pips_debug, pips_user_error, semantics_user_warning, syntax_call, transformer_empty(), and transformer_undefined.

Referenced by pointer_call_expression_to_transformer().

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

◆ pointer_call_expression_to_transformer()

static transformer pointer_call_expression_to_transformer ( entity  e,
expression  expr,
transformer  pre,
bool  is_internal 
)
static

tests are organized to trap 0-ary user-defined functions as well as binary min and max

Parameters
preneeded to compute effects for user calls
is_internalPredicate on current store assumed not modified by expr's side effects

Definition at line 4495 of file expression.c.

4501 {
4502  syntax sexpr = expression_syntax(expr);
4503  call c = syntax_call(sexpr);
4504  entity f = call_function(c);
4505  list args = call_arguments(c);
4507  int arity = gen_length(args);
4508 
4509  pips_debug(8, "Begin with precondition %p\n", pre);
4510  /* tests are organized to trap 0-ary user-defined functions as well as
4511  binary min and max */
4512 
4513  if(ENTITY_MIN0_P(f) || ENTITY_MIN_P(f)) {
4514  tf = min0_to_transformer(e, args, pre, is_internal);
4515  }
4516  else if(ENTITY_C_MIN_P(f)) {
4517  args=CDR(args);
4518  --arity;
4519  tf = min0_to_transformer(e,args,pre,is_internal);
4520  }
4521  else if(ENTITY_MAX0_P(f) || ENTITY_MAX_P(f)) {
4522  tf = max0_to_transformer(e, args, pre, is_internal);
4523  }
4524  else if(ENTITY_COMMA_P(f)) {
4525  // is_internal is dropped...
4526  tf = any_expressions_to_transformer(e, args, pre);
4527  }
4528  else if(ENTITY_CONDITIONAL_P(f)) {
4529  tf = any_conditional_to_transformer(e, args, pre);
4530  }
4531  else if(value_code_p(entity_initial(f)) &&
4533  tf = user_function_call_to_transformer(e, expr, pre);
4534  }
4535  else {
4536  switch(arity) {
4537  case 0:
4538  {
4539  // expr is a constant
4540  //tf = constant_to_transformer(e, expr);
4541  // occur for arithmetic for pointer
4542  // multiply the constant with he sizeof lhs
4543  // compute the multiply with sizeof
4544  tf = expression_multiply_sizeof_to_transformer(e, expr, pre, is_internal);
4545 
4546  break;
4547  }
4548  case 1:
4549  {
4550  expression e1 = EXPRESSION(CAR(args));
4551  tf = pointer_unary_operation_to_transformer(e, f, e1, pre, is_internal);
4552  break;
4553  }
4554  case 2:
4555  {
4556  //expression e1 = EXPRESSION(CAR(args));
4557  //expression e2 = EXPRESSION(CAR(CDR(args)));
4558  tf = pointer_binary_operation_to_transformer(e, expr, pre, is_internal);
4559  break;
4560  }
4561  default:
4562  semantics_user_warning("Operator %s not analyzed\n", entity_name(f));
4563  }
4564  }
4565 
4566  pips_debug(8, "End with tf=%p\n", tf);
4567 
4568  return tf;
4569 }
static transformer pointer_unary_operation_to_transformer(entity e, entity op, expression e1, transformer pre, bool is_internal)
Definition: expression.c:4316
static transformer pointer_binary_operation_to_transformer(entity e, expression expr, transformer pre, bool is_internal)
Definition: expression.c:4415

References any_conditional_to_transformer(), any_expressions_to_transformer(), call_arguments, call_function, CAR, CDR, ENTITY_C_MIN_P, ENTITY_COMMA_P, ENTITY_CONDITIONAL_P, entity_initial, ENTITY_MAX0_P, ENTITY_MAX_P, ENTITY_MIN0_P, ENTITY_MIN_P, entity_name, EXPRESSION, expression_multiply_sizeof_to_transformer(), expression_syntax, f(), gen_length(), get_bool_property(), max0_to_transformer(), min0_to_transformer(), pips_debug, pointer_binary_operation_to_transformer(), pointer_unary_operation_to_transformer(), SEMANTICS_INTERPROCEDURAL, semantics_user_warning, syntax_call, transformer_undefined, user_function_call_to_transformer(), and value_code_p.

Referenced by pointer_expression_to_transformer().

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

◆ pointer_expression_to_transformer()

transformer pointer_expression_to_transformer ( entity  v,
expression  expr,
transformer  pre,
bool  is_internal 
)

This function may return an undefined transformers if it fails to capture the semantics of expr in the polyhedral framework. cf any_expression_to_transformer which call it

Parameters
vvalue of the expression
exprpointer expression
pretransformer, no side effect
is_internal?? use in generic_reference_to_transformer
Returns
transformer with the pointer expression or transformer_undefined if failed

Assume: v is a value

Parameters
exprxpr
prere
is_internals_internal

Definition at line 4582 of file expression.c.

4586 {
4588  syntax sexpr = expression_syntax(expr);
4589 
4590  ifdebug(8) {
4591  pips_debug(8, "begin with precondition %p for expression: ", pre);
4592  print_expression(expr);
4593  }
4594 
4595  /* Assume: v is a value */
4596  switch (syntax_tag(sexpr)) {
4597  case is_syntax_call:
4598  {
4599  tf = transformer_undefined;
4600  tf = pointer_call_expression_to_transformer(v, expr, pre, is_internal);
4601  break;
4602  }
4603  case is_syntax_reference:
4604  {
4605  // pips_user_warning("reference for pointer analysis not be tested\n");
4606  // can occur for arithmetic for pointer
4607  reference rexpr = syntax_reference(sexpr);
4608 
4609  entity rvexpr = reference_variable(rexpr);
4610  type texpr = entity_type(rvexpr);
4611  type bctexpr = compute_basic_concrete_type(texpr);
4612  if(type_variable_p(bctexpr)) {
4613  variable vexpr = type_variable(bctexpr);
4614  if (!volatile_variable_p(vexpr)
4615  && ENDP(variable_dimensions(vexpr))
4616  && !basic_pointer_p(variable_basic(vexpr))) {
4617  // compute the multiply with sizeof
4618  tf = expression_multiply_sizeof_to_transformer(v, expr, pre, is_internal);
4619  }
4620  else
4621  tf = generic_reference_to_transformer(v, rexpr, pre, is_internal);
4622  }
4623  break;
4624  }
4625  case is_syntax_cast:
4626  {
4627  cast c = syntax_cast(sexpr);
4628  type ct = cast_type(c);
4629  expression cexp = cast_expression(c);
4630  type cexpt = expression_to_type(cexp);
4631 
4632  if (expression_null_p(expr)) {
4633  // make the transformer for the equality (take from generic_reference_to_transformer)
4635  if(!transformer_undefined_p(pre)) {
4636  // FI: assume pre is a range
4637  tf = transformer_intersection(tfr, pre);
4638  }
4639  free_transformer(tfr);
4640  } else {
4641  semantics_user_warning("Cast for pointer analysis not tested "
4642  "(except for NULL pointer).\n");
4643  if (type_equal_p(ct, cexpt))
4644  tf = pointer_expression_to_transformer(v, cexp, pre, is_internal);
4645  else
4646  tf = transformer_undefined;
4647  //pips_internal_error("Illegal tag %d", syntax_tag(sexpr));
4648  free_type(cexpt);
4649  }
4650  break;
4651  }
4652  default:
4653  tf = transformer_undefined;
4654  //pips_internal_error("Illegal tag %d", syntax_tag(sexpr));
4655  }
4656 
4657  pips_debug(8, "end with tf=%p\n", tf);
4658 
4659  return tf;
4660 }
entity null_pointer_value_entity(void)
bool volatile_variable_p(variable)
Definition: variable.c:1649
#define variable_dimensions(x)
Definition: ri.h:3122
static transformer pointer_call_expression_to_transformer(entity e, expression expr, transformer pre, bool is_internal)
Definition: expression.c:4495

References basic_pointer_p, cast_expression, cast_type, compute_basic_concrete_type(), ENDP, entity_type, expression_multiply_sizeof_to_transformer(), expression_null_p(), expression_syntax, expression_to_type(), free_transformer(), free_type(), generic_reference_to_transformer(), ifdebug, is_syntax_call, is_syntax_cast, is_syntax_reference, null_pointer_value_entity(), pips_debug, pointer_call_expression_to_transformer(), print_expression(), reference_variable, semantics_user_warning, simple_equality_to_transformer(), syntax_cast, syntax_reference, syntax_tag, transformer_intersection(), transformer_undefined, transformer_undefined_p, type_equal_p(), type_variable, type_variable_p, variable_basic, variable_dimensions, and volatile_variable_p().

Referenced by any_expression_to_transformer().

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

◆ pointer_unary_operation_to_transformer()

static transformer pointer_unary_operation_to_transformer ( entity  e,
entity  op,
expression  e1,
transformer  pre,
bool  is_internal 
)
static

FI: Oops, the precondition is lost here! See any_basic_update_to_transformer()

Parameters
is_internalPredicate on current store assumed not modified by expr's side effects

Definition at line 4316 of file expression.c.

4323 {
4325 
4326  //tf = generic_unary_operation_to_transformer(e, op, e1, pre, is_internal);
4327  // NL: can't call generic_unary_operation_to_transformer because of the case ABS
4328  // it's a copy of generic_unary_operation_to_transformer without the case ABS
4329  // add the case ADDRESS_OF
4330  if(ENTITY_DEREFERENCING_P(op)) {
4331  // tf = generic_unary_operation_to_transformer(e, op, e1, pre, is_internal);
4332  ; // Peformed at the end of the function
4333  }
4334  else if(ENTITY_UNARY_MINUS_P(op)) {
4335  tf = unary_minus_operation_to_transformer(e, e1, pre, is_internal);
4336  }
4339  syntax s1 = expression_syntax(e1);
4341 
4342  if(entity_has_values_p(v1)) {
4344  if(transformer_undefined_p(pre)) {
4345  tf = tfu;
4346  }
4347  else {
4348  /* FI: Oops, the precondition is lost here! See any_basic_update_to_transformer() */
4349  tf = transformer_combine(transformer_range(pre), tfu);
4350  free_transformer(tfu);
4351  }
4352  }
4353  }
4354  else if (ENTITY_ADDRESS_OF_P(op)) {
4355  syntax s1 = expression_syntax(e1);
4356 
4357  if (syntax_reference_p(s1)) {
4359  // entity v1 = reference_variable(r1);
4360 
4361  // create an entity for the address_of
4362  // add_address_of_value(r1, entity_type(e));
4363  // get the address_of entity
4364  // entity a1 = reference_to_address_of_value(r1);
4366  if(entity_undefined_p(a1)) {
4367  tf = transformer_identity(); // transformer_undefined might work too
4368  }
4369  else {
4370  // FI: is a1 usable ?
4371  if(entity_has_values_p(a1)) {
4372  // make the transformer for the equality (take from generic_reference_to_transformer)
4373  transformer tfr = simple_equality_to_transformer(e, a1, false);
4374  if(!transformer_undefined_p(pre)) {
4375  // FI: assume pre is a range
4376  tf = transformer_intersection(tfr, pre);
4377  }
4378  free_transformer(tfr);
4379  }
4380  else {
4381  tf = transformer_identity(); // transformer_undefined might work too
4382  }
4383  }
4384  }
4385  else if (syntax_call_p(s1)) {
4386  call c1 = syntax_call(s1);
4387  entity f1 = call_function(c1);
4388  // list args = call_arguments(c1);
4389 
4390  if (ENTITY_FIELD_P(f1)||ENTITY_POINT_TO_P(f1)) {
4391  //pips_internal_error("ADDRESS_OF for Struct : Not Implemented yet\n");
4392  tf = generic_unary_operation_to_transformer(e, op, e1, pre, is_internal);
4393  }
4394  else {
4395  //Normally this case never appear
4396  pips_internal_error("illegal expression_syntax, syntax_call_function\n syntax_tag : %i\n call_function : %s\n",
4397  syntax_tag(s1), entity_name(f1));
4398  }
4399  }
4400  else {
4401  //Normally this case never appear
4402  pips_internal_error("illegal expression_syntax, syntax_tag : %i",
4403  syntax_tag(s1));
4404  }
4405  }
4406 
4407  if(transformer_undefined_p(tf)) {
4408  // tf = points_to_unary_operation_to_transformer(e, op, e1, pre, is_internal, true);
4409  tf = generic_unary_operation_to_transformer(e, op, e1, pre, is_internal);
4410  }
4411 
4412  return tf;
4413 }
#define ENTITY_ADDRESS_OF_P(e)

References any_basic_update_operation_to_transformer(), call_function, constant_memory_access_path_to_location_entity(), ENTITY_ADDRESS_OF_P, ENTITY_DEREFERENCING_P, ENTITY_FIELD_P, entity_has_values_p(), entity_name, ENTITY_POINT_TO_P, ENTITY_POST_DECREMENT_P, ENTITY_POST_INCREMENT_P, ENTITY_PRE_DECREMENT_P, ENTITY_PRE_INCREMENT_P, ENTITY_UNARY_MINUS_P, entity_undefined_p, expression_syntax, free_transformer(), generic_unary_operation_to_transformer(), pips_internal_error, reference_variable, s1, simple_equality_to_transformer(), syntax_call, syntax_call_p, syntax_reference, syntax_reference_p, syntax_tag, transformer_combine(), transformer_identity(), transformer_intersection(), transformer_range(), transformer_undefined, transformer_undefined_p, and unary_minus_operation_to_transformer().

Referenced by pointer_call_expression_to_transformer().

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

◆ points_to_unary_operation_to_transformer()

transformer points_to_unary_operation_to_transformer ( entity  e,
entity  op,
expression  e1,
transformer  pre,
bool  is_internal,
bool  is_pointer 
)

This function is redundant with generic_unary_operation_to_transformer() except for its use of parameter is_pointer.

Parameters
opp
e11
prere
is_internals_internal
is_pointers_pointer

Definition at line 2770 of file expression.c.

2776 {
2777  pips_debug(8, "begin \n");
2779 
2780  if (!pt_to_list_undefined_p()) {
2781  // FI: may have to be adapted to implement ANALYZE_CONSTANT_PATHS
2782  //statement curstat = get_current_statement_from_statement_global_stack();
2783  //points_to_graph ptg = get_points_to_graph_from_statement(curstat);
2784 
2786  // compute the assignment for each cell pointed with the convex hull
2787  FOREACH(CELL, cp, l) {
2789  entity rhs = reference_variable(rrhs);
2790 
2791  if (!is_pointer && entity_null_locations_p(rhs)) {
2792  if (gen_length(l) == 1) {
2793  tf = transformer_empty();
2794  pips_user_error("The pointer %s points to NULL\n", expression_to_string(e1));
2795  }
2796  else {
2797  semantics_user_warning("The pointer %s can points to NULL\n", expression_to_string(e1));
2798  }
2799  } else if (entity_typed_nowhere_locations_p(rhs)) {
2800  if (gen_length(l) == 1) {
2801  tf = transformer_empty();
2802  pips_user_error("The pointer %s points to undefined/indeterminate (%s)\n", expression_to_string(e1), reference_to_string(rrhs));
2803  }
2804  else {
2805  semantics_user_warning("The pointer %s can points to undefined/indeterminate (%s)\n", expression_to_string(e1), reference_to_string(rrhs));
2806  }
2807  }
2808  else {
2809  // check if rrhs is a constant path and can be analyze or not
2810  // (not really exact, see detail in analyzed_reference_p)
2811  if (analyzed_reference_p(rrhs)) {
2812  transformer rt = generic_reference_to_transformer(e, rrhs, pre, is_internal);
2813  // NL : It must have be a better way to do that but I don't know how
2814  if (transformer_undefined_p(tf))
2815  tf = rt;
2816  else {
2817  tf = transformer_convex_hull(tf, rt);
2818  free_transformer(rt);
2819  }
2820  }
2821  }
2822  }
2823  }
2824 
2825  if (transformer_undefined_p(tf)) {
2827  if(test_warning_counters()) {
2828  extern bool active_phase_p(const char *);
2829  if(active_phase_p("TRANSFORMERS_INTER_FULL_WITH_POINTS_TO")) {
2830  if(get_bool_property("SEMANTICS_ANALYZE_CONSTANT_PATH"))
2831  ;
2832  else
2833  semantics_user_warning("Set property SEMANTICS_ANALYZE_CONSTANT_PATH TRUE."
2834  " It might generate more accurate transformers.\n");
2835  }
2836  else {
2837  if(get_bool_property("SEMANTICS_ANALYZE_CONSTANT_PATH"))
2838  semantics_user_warning("Activate TRANSFORMERS_INTER_FULL_WITH_POINTS_TO."
2839  " It might generate more accurate transformers.\n");
2840  else
2841  semantics_user_warning("Activate TRANSFORMERS_INTER_FULL_WITH_POINTS_TO and "
2842  "setproperty SEMANTICS_ANALYZE_CONSTANT_PATH TRUE."
2843  " It might generate more accurate transformers.\n");
2844  }
2845  }
2846  }
2847  }
2848 
2849  ifdebug (8) dump_transformer(tf);
2850  pips_debug(8, "end \n");
2851  return tf;
2852 }
bool active_phase_p(const char *phase)
Definition: activate.c:80
bool entity_null_locations_p(entity e)
test if an entity is the NULL POINTER
bool entity_typed_nowhere_locations_p(entity e)
test if an entity is the bottom of the lattice
bool test_warning_counters(void)
#define cell_reference(x)
Definition: effects.h:469
#define cell_preference(x)
Definition: effects.h:472
#define cell_preference_p(x)
Definition: effects.h:470
char end
Definition: gtk_status.c:82
string reference_to_string(reference r)
Definition: expression.c:87
#define preference_reference(x)
Definition: ri.h:2102

References active_phase_p(), analyzed_reference_p(), CELL, cell_preference, cell_preference_p, cell_reference, cp, dump_transformer, ENTITY_DEREFERENCING_P, ENTITY_FIELD_P, entity_null_locations_p(), ENTITY_POINT_TO_P, entity_typed_nowhere_locations_p(), expression_to_string(), FOREACH, free_transformer(), gen_length(), generic_reference_to_transformer(), get_bool_property(), ifdebug, pips_debug, pips_user_error, preference_reference, pt_to_list_undefined_p(), reference_to_string(), reference_variable, semantics_expression_to_points_to_sinks(), semantics_user_warning, test_warning_counters(), transformer_convex_hull(), transformer_empty(), transformer_undefined, and transformer_undefined_p.

+ Here is the call graph for this function:

◆ precondition_add_condition_information()

transformer precondition_add_condition_information ( transformer  pre,
expression  c,
transformer  context,
bool  veracity 
)

context might be derivable from pre as transformer_range(pre) but this is sometimes very computationally intensive, e.g.

in ocean.

Parameters
prere
contextontext
veracityeracity

Definition at line 1111 of file expression.c.

1116 {
1118 
1122  (pre, c, context, veracity, false);
1123  }
1124  else {
1125  transformer new_context = transformer_range(context);
1126 
1128  (pre, c, new_context, veracity, false);
1129  free_transformer(new_context);
1130  }
1131 
1134 
1135  return post;
1136 }
Definition: delay.c:253
void reset_temporary_value_counter(void)
Definition: value.c:250

References ENDP, free_transformer(), reset_temporary_value_counter(), transformer_add_condition_information_updown(), transformer_arguments, transformer_range(), transformer_temporary_value_projection(), transformer_undefined, and transformer_undefined_p.

Referenced by dag_to_flow_sensitive_preconditions(), eval_condition_wrt_precondition_p(), load_arc_precondition(), process_ready_node(), standard_whileloop_to_transformer(), transformer_add_range_condition(), unstructured_to_postconditions(), whileloop_to_postcondition(), and whileloop_to_total_precondition().

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

◆ precondition_minmax_of_expression()

bool precondition_minmax_of_expression ( expression  exp,
transformer  tr,
intptr_t pmin,
intptr_t pmax 
)

compute integer bounds pmax, pmin of expression exp under preconditions tr require value mappings set !

create a temporary value

compute its preconditions

tidy & return

Parameters
expxp
trr
pminmin
pmaxmax

Definition at line 5818 of file expression.c.

5822 {
5823  bool success;
5824  /* create a temporary value */
5825  basic bas = basic_of_expression(exp);
5827  free_basic(bas);
5828 
5829  /* compute its preconditions */
5830  transformer var_tr = safe_any_expression_to_transformer(var,exp,tr,false);
5831  transformer pre = transformer_apply(var_tr, tr);
5832 
5833  //success = precondition_minmax_of_value(var, var_tr, pmin, pmax);
5834  success = precondition_minmax_of_value(var, pre, pmin, pmax);
5835 
5836  /* tidy & return */
5837  predicate_system(transformer_relation(var_tr))=SC_UNDEFINED;
5838  free_transformer(var_tr);
5839  free_entity(var);
5840  return success;
5841 }
void free_entity(entity p)
Definition: ri.c:2524
#define transformer_relation(x)
Definition: ri.h:2873
#define predicate_system(x)
Definition: ri.h:2069

References basic_of_expression(), exp, free_basic(), free_entity(), free_transformer(), make_local_temporary_value_entity_with_basic(), precondition_minmax_of_value(), predicate_system, safe_any_expression_to_transformer(), transformer_apply(), and transformer_relation.

Referenced by bounds_of_expression(), integer_minmax_to_transformer(), integer_power_to_transformer(), partial_eval_min_or_max_operator(), and simplify_minmax_expression().

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

◆ precondition_minmax_of_value()

bool precondition_minmax_of_value ( entity  val,
transformer  tr,
intptr_t pmin,
intptr_t pmax 
)

compute integer bounds pmax, pmin of value val under preconditions tr require value mappings set !

retrieve the associated psysteme

compute min / max bounds

special case to handle VMIN and VMAX in 32 bits

Parameters
valal
trr
pminmin
pmaxmax

Definition at line 5790 of file expression.c.

5793 {
5794  bool success;
5795  /* retrieve the associated psysteme*/
5797  /* compute min / max bounds */
5798  Value vmin,vmax;
5799  if((success=sc_minmax_of_variable(ps,val,&vmin,&vmax)))
5800  {
5801  /* special case to handle VMIN and VMAX in 32 bits*/
5802  if(vmax != (Value)(intptr_t)(vmax) && vmax == VALUE_MAX) vmax= INT_MAX;
5803  if(vmin != (Value)(intptr_t)(vmin) && vmin == VALUE_MIN) vmin= INT_MIN;
5804  pips_assert("no data loss", vmin == (Value)(intptr_t)(vmin));
5805  pips_assert("no data loss", vmax == (Value)(intptr_t)(vmax));
5806  *pmin=(intptr_t)vmin;
5807  *pmax=(intptr_t)vmax;
5808  }
5809  // FI: ps is destroyed by sc_minmax_of_variable(). Should it
5810  // nevertheless be freed?
5811  return success;
5812 }
#define VALUE_MIN
#define VALUE_MAX
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
bool sc_minmax_of_variable(Psysteme ps, Variable var, Value *pmin, Value *pmax)
void sc_minmax_of_variable(Psysteme ps, Variable var, Value *pmin, *pmax): examine un systeme pour tr...
Definition: sc_eval.c:143

References intptr_t, pips_assert, predicate_system, sc_dup(), sc_minmax_of_variable(), transformer_relation, VALUE_MAX, and VALUE_MIN.

Referenced by add_type_information(), bitwise_xor_to_transformer(), integer_left_shift_to_transformer(), logical_binary_function_to_transformer(), logical_not_to_transformer(), modulo_by_a_constant_to_transformer(), and precondition_minmax_of_expression().

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

◆ process_bounds_for_divide()

static transformer process_bounds_for_divide ( transformer  tf,
entity  v,
entity  v1,
int  lb1,
int  ub1,
entity  v2,
int  lb2,
int  ub2 
)
static

Auxiliary function for non-affine operators such as divide, multiply, modulo...

Returns an equivalent set of interval products whose bounds are always positive plus some information about the global sign for the result. For instance, [-3,4] x [-5,6] is broken down into four products:

  • [1,3] x [1,5] positive
  • [1,3] x [0,6] negative
  • [0,4] x [1,5] negative
  • [0,4] x [0,6] positive

For division, 0 is excluded and the positive intervals start at 1 instead of 0.

Intervals may be empty: [1,0]. DEAD CODE static void break_intervals_into_positive_intervals(int lb1, int ub1, int lb2, int ub2, struct interval_product cases[4], int * pncase, bool exclude_zero_p) { We need a pair of macros to process -MAX_INT and -MIN_INT, MINUS_UPPER_BOUND and MINUS_LOWER_BOUND, because of the disymetry in the encoding of integers

int nlb = exclude_zero_p? 1 : 0; if(false) { pncase = 0; if(lb1>=0) { The first interval is positive if(lb2>=0) { pncase = 1; cases[0].lb1 = lb1, cases[0].ub1 = ub1, cases[0].lb2 = lb2, cases[0].ub2 = ub2, cases[0].positive_p = true; } else if(ub2<=0) { pncase = 1; cases[0].lb1 = lb1, cases[0].ub1 = ub1, cases[0].lb2 = -ub2, cases[0].ub2 = -lb2, cases[0].positive_p = false; } else { The second interval must be broken into two sub-intervals pncase = 2; cases[0].lb1 = lb1, cases[0].ub1 = ub1, cases[0].lb2 = 1, cases[0].ub2 = -lb2, cases[0].positive_p = false; cases[1].lb1 = lb1, cases[1].ub1 = ub1, cases[1].lb2 = nlb, cases[1].ub2 = ub2, cases[1].positive_p = true; } } else if(ub1<=0) { The first interval is negative if(lb2>=0) { pncase = 1; cases[0].lb1 = -ub1, cases[0].ub1 = -lb1, cases[0].lb2 = lb2, cases[0].ub2 = ub2, cases[0].positive_p = false; } else if(ub2<=0) { pncase = 1; cases[0].lb1 = -ub1, cases[0].ub1 = -lb1, cases[0].lb2 = -ub2, cases[0].ub2 = -lb2, cases[0].positive_p = true; } else { The second interval must be broken into two sub-intervals pncase = 2; cases[0].lb1 = -ub1, cases[0].ub1 = -lb1, cases[0].lb2 = 1, cases[0].ub2 = -lb2, cases[0].positive_p = true; cases[1].lb1 = -ub1, cases[1].ub1 = -lb1, cases[1].lb2 = nlb, cases[0].ub2 = ub2, cases[1].positive_p = false; } } else { The first interval must be broken into two sub-intervals if(lb2>=0) { pncase = 2; cases[0].lb1 = 1, cases[0].ub1 = -lb1, cases[0].lb2 = lb2, cases[0].ub2 = ub2, cases[0].positive_p = false; cases[1].lb1 = nlb, cases[1].ub1 = ub1, cases[1].lb2 = lb2, cases[1].ub2 = ub2, cases[1].positive_p = true; } else if(ub2<=0) { pncase = 2; cases[0].lb1 = 1, cases[0].ub1 = -lb1, cases[0].lb2 = -ub2, cases[0].ub2 = -lb2, cases[0].positive_p = true; cases[1].lb1 = 1, cases[1].ub1 = ub1, cases[1].lb2 = -ub2, cases[1].ub2 = -lb2, cases[1].positive_p = false; } else { The second interval must be broken into two sub-intervals pncase = 4; cases[0].lb1 = 1, cases[0].ub1 = -lb1, cases[0].lb2 = 1, cases[0].ub2 = -lb2, cases[0].positive_p = true; cases[1].lb1 = nlb, cases[1].ub1 = ub1, cases[1].lb2 = 1, cases[1].ub2 = -lb2, cases[1].positive_p = false; cases[2].lb1 = 1, cases[2].ub1 = -lb1, cases[2].lb2 = nlb, cases[2].ub2 = ub2, cases[2].positive_p = false; cases[3].lb1 = nlb, cases[3].ub1 = ub1, cases[3].lb2 = nlb, cases[3].ub2 = ub2, cases[3].positive_p = true; } } } else { if(lb2>=0) { pncase = 1; cases[0].lb1 = 1, cases[0].ub1 = 1, cases[0].lb2 = lb2, cases[0].ub2 = ub2, cases[0].positive_p = true; } else if(ub2<=0) { pncase = 1; cases[0].lb1 = 1, cases[0].ub1 = 1, cases[0].lb2 = -ub2, cases[0].ub2 = -lb2, cases[0].positive_p = false; } else { The v2 interval must be broken into two sub-intervals pncase = 2; cases[0].lb1 = 1, cases[0].ub1 = 1, cases[0].lb2 = 1, cases[0].ub2 = -lb2, cases[0].positive_p = false; cases[1].lb1 = 1, cases[1].ub1 = 1, cases[1].lb2 = nlb, cases[1].ub2 = ub2, cases[1].positive_p = true; } } } Equation v = v1/v2 for v1>=0 and v2>=0: v1-v2+1 <= v2 v <= v1

We know positive bounds [lb1,ub1] for v1 and [lb2,ub2] for v2. What do we know about v?

v1-v2+1 <= v2 v <= v1

The only non-affine term is v2 v:

v1-v2+1 <= ub2 v => -ub2 v + v1 - v2 + 1 <= 0 lb2 v <= v1 => lb2 v -v1 <= 0

If -v must be used instead of v:

v1-v2+1 <= -ub2 v => ub2 v <= v2-v1-1 => ub2 v + v1 - v2 + 1 <= 0 -lb2 v <= v1 => lb2 v >= v1 => -lb2 v -v1 <= 0

Else, we can also eliminate v1 and v2 everywhere. Substitute v1 thanks to lb1 <= v1 <= ub1: lb1-v2+1 <= v2 v <= ub1 Substitue the left v2 in the same way: lb1-ub2+1 <= v2 v <= ub1 If lb2==ub2, v2 v is an affine term. Else substitue the central v2 for each inequality: lb2 v <= ub1 => v<= ub1/lb2 lb1-ub2+1 <=ub2 v => v>= lb1/ub2

if the positive flag is not set, v must be replaced by -v: -ub2 v <= ub1 => v>=-ub1/lb2 lb1-ub2+1<=-lb2 v => v<=-lb1/ub2 DEAD CODE static transformer process_interval_for_divide( entity v, entity v1, entity v2, struct interval_product one_case) { long long int lb1 = one_case.lb1; long long int ub1 = one_case.ub1; long long int lb2 = one_case.lb2; long long int ub2 = one_case.ub2; bool positive_p = one_case.positive_p; Two possible options: true and false bool full_elimination = false; transformer itf = transformer_identity(); // no information at first

if(full_elimination) { if(ub1 != INT_MAX && lb2 != INT_MAX) { if(positive_p) itf = transformer_add_inequality_with_integer_constraint(itf, v, ub1/lb2, true); else itf = transformer_add_inequality_with_integer_constraint(itf, v, -(ub1/lb2), false); }

if(lb1 != INT_MAX && ub2 != INT_MAX && lb2 != INT_MAX) { if(positive_p) itf = transformer_add_inequality_with_integer_constraint(itf, v, lb1/ub2, false); else itf = transformer_add_inequality_with_integer_constraint(itf, v, -(lb1/ub2), true); } } else { Minimize the number of substitutions:

If v is positive because v1>=0 and v2 >=0

v1 = v2 v + x ^ 0<=x<=v2-1 if v1 >= 0 && v2 >= 0 v1 <= v2 v + v2 -1 ^ v1>= v2 v ^ lb2 <= v2 <= ub2 v1-v2+1 <= ub2 v => -ub2 v + v1 - v2 + 1 <= 0 lb2 v <= v1 => lb2 v -v1 <= 0

If v is negative because v1 <=0 and v2 >=0:

v1 = v2 v + x ^ -v2+1<=x<=0 if v1 <= 0 && v2 >= 0 v1 <= v2 v ^ v1>= v2 v - v2 + 1 v1 <= lb2 v => -lb2 v + v1 <= 0 ub2 v -v2 +1 <= v1 => ub2 v -v1 -v2 + 1 <= 0

If v2 <= 0, use -v2 and -v1? if(positive_p) { itf = transformer_add_3d_affine_constraint(itf, -ub2, v, 1, v1, -1, v2, 1, false); itf = transformer_add_3d_affine_constraint(itf, lb2, v, -1, v1, 0, v2, 0, false); } else { itf = transformer_add_3d_affine_constraint(itf, ub2, v, 1, v1, -1, v2, 1, false); itf = transformer_add_3d_affine_constraint(itf, -lb2, v, -1, v1, 0, v2, 0, false); } }

return itf; }

static transformer process_intervals_for_divide( transformer tf, entity v, entity v1, entity v2, struct interval_product cases[4], int ncase) { int i; transformer dtf = transformer_empty();

if(false) { Perform the convex hull before the intersection is faster but less accurate in general, maybe not when v1 and v2 have been fully eliminated. for(i=0; i<ncase; i++) { transformer itf = process_interval_for_divide(v, v1, v2, cases[i]); dtf = transformer_convex_hull(dtf, itf); } To be checked for functionality and memory leaks tf = transformer_image_intersection(tf, dtf); } else { for(i=0; i<ncase; i++) { transformer itf = process_interval_for_divide(v, v1, v2, cases[i]); transformer ctf = transformer_combine(copy_transformer(tf), itf); free_transformer(itf); memory leak transformer ndtf = transformer_convex_hull(dtf, ctf); free_transformer(dtf); free_transformer(ctf); dtf = ndtf; } To be checked for functionality and memory leaks tf = dtf; }

return tf; } The equation v1 = v2 v + r is always true. But we need to eliminate the remainder r which is implicit and to linearize the product v2 v to obtain affine constraints of v, v1, v2, using constant lb1, ub1, lb2 and ub2, with lb1 <= v1 <= ub1 and lb2 <= v2 <=ub2.

v2 is positive and r is positive: 0 <= r <= v2 - 1 v1 = v2 v + r v1 <= v2 v + v2 - 1 v1 >= v2 v lb2 <= v2 <= ub2 => lb2 v <= v2 v <= ub2 v => v1 <= ub2 v + v2 -1 => -ub2 v + v1 - v2 + 1 <= 0 => v1 >= lb2 v => lb2 v - v1 <=0

v2 is positive and r is negative: -v2 + 1 <= r <= 0 v1 = v2 v + r v1 <= v2 v
v1 >= v2 v - v2 + 1 lb2 <= v2 <= ub2 => ub2 v <= v2 v <= lb2 v => v1 <= lb2 v => -lb2 v + v1 <= 0 => v1 >= ub2 v -v2 + 1 => ub2 v - v1 -v2 + 1 <=0

v2 is positive and r is bounded: -v2 + 1 <= r <= v2 - 1 v1 = v2 v + r v1 <= v2 v + v2 - 1 v1 >= v2 v - v2 + 1 I do not know how to linearize v2 v, unless v2 is a constant, but v1/v2 can be bounded: lb1 <= v1 <= ub1 => lb1/v2 <= v1/v2 <= ub1/v2 => lb1/lb2 <= v <= ub1/lb2

Also, when v2 is a numerical constant, if exists x s.t. v1 == v2 x, then v == x. This is not exploited here.

v2 is negative and r is positive: 0 <= r <= -v2 - 1 v1 = v2 v + r v1 <= v2 v - v2 - 1 v1 >= v2 v lb2 <= v2 <= ub2 => ub2 v <= v2 v <= lb2 v (since v is negative) => v1 <= lb2 v - v2 -1 => -lb2 v + v1 + v2 + 1 <= 0 => v1 >= ub2 v => ub2 v - v1 <=0

v2 is negative and r is negative: v2 + 1 <= r <= 0 v1 = v2 v + r v1 <= v2 v
v1 >= v2 v + v2 + 1 lb2 <= v2 <= ub2 => lb2 v <= v2 v <= ub2 v (since v is positive) => v1 <= ub2 v => -ub2 v + v1 <= 0 => v1 >= lb2 v + v2 + 1 => lb2 v - v1 + v2 + 1 <=0

v2 is negative and r is bounded: v2 + 1 <= r <= -v2 - 1 v1 = v2 v + r v1 <= v2 v - v2 - 1 => -v2 v + v1 + v2 + 1 <= 0 v1 >= v2 v + v2 + 1 => v2 v - v1 + v2 + 1 <=0 I do not know how to linearize v2 v, but v1/v2 can be bounded: lb1 <= v1 <= ub1 => lb1/v2 >= v1/v2 >= ub1/v2 => ub1/ub2 <= v <= lb1/ub2

We are left with dividing interval [lb1, ub1] by interval [lb2, ub2] knowing that lb1 and lb2 are negative and ub1 and ub2 positive. Since 1 and -1 belongs to [lb2, ub2], the upper bound is max(ub1, -lb1) and the lower bound is min(-ub1, lb1).

Definition at line 3141 of file expression.c.

3142 {
3143  if(lb2==0&&ub2==0) { // zero divide
3144  semantics_user_warning("Zero divide:\n");
3145  free_transformer(tf);
3146  tf = transformer_empty();
3147  }
3148  else if(lb2>=0) { // division by a strictly positive number
3149  if(lb2==0)
3150  lb2 = 1;
3151  if(lb1>=0) { // of a positive number: divide01
3152  /* v2 is positive and r is positive: 0 <= r <= v2 - 1
3153  * v1 = v2 v + r
3154  * v1 <= v2 v + v2 - 1
3155  * v1 >= v2 v
3156  * lb2 <= v2 <= ub2 => lb2 v <= v2 v <= ub2 v
3157  * => v1 <= ub2 v + v2 -1 => -ub2 v + v1 - v2 + 1 <= 0
3158  * => v1 >= lb2 v => lb2 v - v1 <=0
3159  */
3160  if(ub2!=INT_MAX)
3161  tf = transformer_add_3d_affine_constraint(tf, -ub2, v, 1, v1, -1, v2, 1, false);
3162  else
3163  tf = transformer_add_3d_affine_constraint(tf, -1, v, 0, v1, 0, v2, 0, false);
3164  tf = transformer_add_3d_affine_constraint(tf, lb2, v, -1, v1, 0, v2, 0, false);
3165  }
3166  else if(ub1<=0) { // of a negative number: divide02
3167  /* v2 is positive and r is negative: -v2 + 1 <= r <= 0
3168  * v1 = v2 v + r
3169  * v1 <= v2 v
3170  * v1 >= v2 v - v2 + 1
3171  * lb2 <= v2 <= ub2 => ub2 v <= v2 v <= lb2 v
3172  * => v1 <= lb2 v => -lb2 v + v1 <= 0
3173  * => v1 >= ub2 v -v2 + 1 => ub2 v - v1 -v2 + 1 <=0
3174  */
3175  tf = transformer_add_3d_affine_constraint(tf, -lb2, v, 1, v1, 0, v2, 0, false);
3176  if(ub2!=INT_MAX)
3177  tf = transformer_add_3d_affine_constraint(tf, ub2, v, -1, v1, -1, v2, 1, false);
3178  else
3179  tf = transformer_add_3d_affine_constraint(tf, 1, v, 0, v1, 0, v2, 0, false);
3180  }
3181  else { // of a number of unknown sign
3182  /* v2 is positive and r is bounded: -v2 + 1 <= r <= v2 - 1
3183  * v1 = v2 v + r
3184  * v1 <= v2 v + v2 - 1
3185  * v1 >= v2 v - v2 + 1
3186  * I do not know how to linearize v2 v, unless v2 is a constant,
3187  * but v1/v2 can be bounded:
3188  * lb1 <= v1 <= ub1 => lb1/v2 <= v1/v2 <= ub1/v2 => lb1/lb2 <= v <= ub1/lb2
3189  *
3190  * Also, when v2 is a numerical constant, if exists x s.t. v1 ==
3191  * v2 x, then v == x. This is not exploited here.
3192  */
3193  if(lb2==ub2) { // v2 v is a linear term, Semantics-New/S124, divide07
3194  // - v2 v + v1 - v2 + 1 <=0
3195  tf = transformer_add_3d_affine_constraint(tf, -lb2, v, 1, v1, -1, v2, 1, false);
3196  // v2 v - v1 - v2 +1 <=0
3197  tf = transformer_add_3d_affine_constraint(tf, lb2, v, -1, v1, -1, v2, 1, false);
3198  }
3199  if(lb1!=INT_MIN)
3200  tf = transformer_add_3d_affine_constraint(tf, -1, v, 0, v1, 0, v2, lb1/lb2, false);
3201  if(ub1!=INT_MAX)
3202  tf = transformer_add_3d_affine_constraint(tf, 1, v, 0, v1, 0, v2, ub1/lb2, false);
3203  }
3204  }
3205  else if(ub2<=0) { // division by a strictly negative number
3206  if(ub2==0)
3207  ub2 = -1;
3208  if(lb1>=0) { // of a positive number, e.g. 100/-3 = -33 (r=1), divide03
3209  /* v2 is negative and r is positive: 0 <= r <= -v2 - 1
3210  * v1 = v2 v + r
3211  * v1 <= v2 v - v2 - 1
3212  * v1 >= v2 v
3213  * lb2 <= v2 <= ub2 => ub2 v <= v2 v <= lb2 v (since v is negative)
3214  * => v1 <= lb2 v - v2 -1 => -lb2 v + v1 + v2 + 1 <= 0
3215  * => v1 >= ub2 v => ub2 v - v1 <=0
3216  */
3217  if(lb2!=INT_MAX)
3218  tf = transformer_add_3d_affine_constraint(tf, -lb2, v, 1, v1, 1, v2, 1, false);
3219  else
3220  tf = transformer_add_3d_affine_constraint(tf, 1, v, 0, v1, 0, v2, 0, false);
3221  tf = transformer_add_3d_affine_constraint(tf, ub2, v, -1, v1, 0, v2, 0, false);
3222  }
3223  else if(ub1<=0) {// of a negative number, e.g. -100/-3 = 33 (r=-1), divide04
3224  /* v2 is negative and r is negative: v2 + 1 <= r <= 0
3225  * v1 = v2 v + r
3226  * v1 <= v2 v
3227  * v1 >= v2 v + v2 + 1
3228  * lb2 <= v2 <= ub2 => lb2 v <= v2 v <= ub2 v (since v is positive)
3229  * => v1 <= ub2 v => -ub2 v + v1 <= 0
3230  * => v1 >= lb2 v + v2 + 1 => lb2 v - v1 + v2 + 1 <=0
3231  */
3232  tf = transformer_add_3d_affine_constraint(tf, -ub2, v, 1, v1, 0, v2, 0, false);
3233  if(lb2!=INT_MIN)
3234  tf = transformer_add_3d_affine_constraint(tf, lb2, v, -1, v1, 1, v2, 1, false);
3235  else
3236  tf = transformer_add_3d_affine_constraint(tf, -1, v, 0, v1, 0, v2, 0, false);
3237  }
3238  else { // of a number of unknown sign
3239  /* v2 is negative and r is bounded: v2 + 1 <= r <= -v2 - 1
3240  * v1 = v2 v + r
3241  * v1 <= v2 v - v2 - 1 => -v2 v + v1 + v2 + 1 <= 0
3242  * v1 >= v2 v + v2 + 1 => v2 v - v1 + v2 + 1 <=0
3243  * I do not know how to linearize v2 v, but v1/v2 can be bounded:
3244  * lb1 <= v1 <= ub1 => lb1/v2 >= v1/v2 >= ub1/v2 => ub1/ub2 <= v <= lb1/ub2
3245  */
3246  if(lb2==ub2) {
3247  tf = transformer_add_3d_affine_constraint(tf, -lb2, v, 1, v1, 1, v2, 1, false);
3248  tf = transformer_add_3d_affine_constraint(tf, lb2, v, -1, v1, 1, v2, 1, false);
3249  }
3250  if(ub1!=INT_MAX)
3251  tf = transformer_add_3d_affine_constraint(tf, -1, v, 0, v1, 0, v2, ub1/ub2, false);
3252  if(lb1!=INT_MIN)
3253  tf = transformer_add_3d_affine_constraint(tf, 1, v, 0, v1, 0, v2, -lb1/ub2, false);
3254  }
3255  }
3256  else { // No sign information is available for v1 or v2
3257  /* We are left with dividing interval [lb1, ub1] by interval [lb2,
3258  * ub2] knowing that lb1 and lb2 are negative and ub1 and ub2
3259  * positive. Since 1 and -1 belongs to [lb2, ub2], the upper bound
3260  * is max(ub1, -lb1) and the lower bound is min(-ub1, lb1).
3261  */
3262  if(lb1!=INT_MIN && ub1!=INT_MAX) { // divide05, divide06
3263  int u = ub1>=-lb1? ub1: -lb1;
3264  int l = -ub1<=lb1? -ub1: lb1;
3265  // l <= v <= u
3266  tf = transformer_add_3d_affine_constraint(tf, 1, v, 0, v1, 0, v2, -u, false);
3267  tf = transformer_add_3d_affine_constraint(tf, -1, v, 0, v1, 0, v2, l, false);
3268  }
3269  }
3270  return tf;
3271 }
transformer transformer_add_3d_affine_constraint(transformer tf, int a1, entity v1, int a2, entity v2, int a3, entity v3, int cst, bool equation_p)
Add the constraint a1 v1 + a2 v2 + a3 v3 + cst <= or == 0.
Definition: basic.c:536

References free_transformer(), semantics_user_warning, transformer_add_3d_affine_constraint(), and transformer_empty().

Referenced by integer_binary_operation_to_transformer().

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

◆ safe_any_assign_operation_to_transformer()

transformer safe_any_assign_operation_to_transformer ( entity  tmp,
list  args,
transformer  pre,
bool  is_internal 
)
Parameters
tmpmp
argsrgs
prearguments for assign
is_internalprecondition

Definition at line 575 of file expression.c.

579 {
580  transformer tf = any_assign_operation_to_transformer(tmp, args, pre, is_internal);
581  if(transformer_undefined_p(tf)) {
582  // FI: I'd like tmp to appear in the basis...
583  tf = transformer_identity();
584  }
585  return tf;
586 }

References any_assign_operation_to_transformer(), transformer_identity(), and transformer_undefined_p.

+ Here is the call graph for this function:

◆ safe_any_expression_side_effects_to_transformer()

transformer safe_any_expression_side_effects_to_transformer ( expression  e,
transformer  p,
bool  is_internal 
)

Same as any_expression_side_effects_to_transformer() but effects are used to always generate a transformer.

FI: I do not know how effects should be used. It might be useful to allow special transformers using location abstraction to simplify the recurrence. Currently, effects are used or not. It might be necessary to use only some of them at a given time in the evaluation process as variables can be assigned almost anywhere in C.

Parameters
is_internals_internal

Definition at line 4947 of file expression.c.

4951 {
4952  transformer tf =
4953  any_expression_side_effects_to_transformer(e, p, is_internal);
4954  if(transformer_undefined_p(tf)) {
4956  }
4957 
4958  return tf;
4959 }

References any_expression_side_effects_to_transformer(), expression_effects_to_transformer(), and transformer_undefined_p.

+ Here is the call graph for this function:

◆ safe_any_expression_to_transformer()

transformer safe_any_expression_to_transformer ( entity  v,
expression  expr,
transformer  pre,
bool  is_internal 
)

Always return a usable transformer.

Use effects if no better transformer can be found

Parameters
exprxpr
prere
is_internals_internal

Definition at line 5156 of file expression.c.

5161 {
5164  transformer tf = any_expression_to_transformer(v, expr, npre, is_internal);
5165 
5166  if(transformer_undefined_p(tf)) {
5167  //list el = expression_to_proper_effects(expr);
5169  tf = effects_to_transformer(el);
5170 
5171  /*
5172  pips_assert("effect references are protected by persistant",
5173  effect_list_can_be_safely_full_freed_p(el));*/
5174 
5176 
5177  gen_full_free_list(el);
5178  }
5179  free_transformer(npre);
5180 
5181  return tf;
5182 }
bool effect_list_can_be_safely_full_freed_p(list)
Check if some references might be freed with the effects.
Definition: effects.c:1159

References any_expression_to_transformer(), copy_transformer(), effect_list_can_be_safely_full_freed_p(), effects_to_transformer(), expression_to_proper_constant_path_effects(), free_transformer(), gen_full_free_list(), transformer_identity(), and transformer_undefined_p.

Referenced by add_index_bound_conditions(), addition_operation_to_transformer(), any_conditional_to_transformer(), any_expressions_to_transformer(), any_user_call_site_to_transformer(), bitwise_xor_to_transformer(), condition_to_transformer(), fortran_data_to_prec_for_variables(), logical_not_to_transformer(), modulo_to_transformer(), precondition_minmax_of_expression(), transformer_add_any_relation_information(), and update_cp_with_rhs_to_transformer().

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

◆ safe_expression_to_transformer()

transformer safe_expression_to_transformer ( expression  exp,
transformer  pre 
)

This simple function does not take points-to information into account. Furthermore, precise points-to information is not available when side effects occur as in comma expressions.

FI: I do not see a simple way out. I can try to fix partly the problem in statement_to_transformer where the effects are known... Or I can play safer and use an effect function that replaces dereferencements by anywhere effects.

See anywhere03.c as an example of the issue.

Parameters
expxp
prere

Definition at line 5307 of file expression.c.

5308 {
5309  /* This simple function does not take points-to information into
5310  account. Furthermore, precise points-to information is not
5311  available when side effects occur as in comma expressions.
5312 
5313  FI: I do not see a simple way out. I can try to fix partly the
5314  problem in statement_to_transformer where the effects are
5315  known... Or I can play safer and use an effect function that
5316  replaces dereferencements by anywhere effects.
5317 
5318  See anywhere03.c as an example of the issue.
5319  */
5321  // To be careful with extended expressions generated by points-to information
5324  entity v = reference_variable(r);
5325  if(entity_field_p(v)) { // s[var1], not effect no a constant
5326  tf = transformer_identity();
5327  }
5328  }
5329 
5330  if(transformer_undefined_p(tf)) {
5331  //list el = expression_to_proper_effects(exp);
5333  tf = expression_to_transformer(exp, pre, el);
5334 
5335  gen_full_free_list(el);
5336  }
5337 
5338  return tf;
5339 }
bool entity_field_p(entity e)
e is the field of a structure
Definition: entity.c:857
transformer expression_to_transformer(expression exp, transformer pre, list el)
Just to capture side effects as the returned value is ignored.
Definition: expression.c:5190

References entity_field_p(), exp, expression_reference(), expression_reference_p(), expression_to_proper_constant_path_effects(), expression_to_transformer(), gen_full_free_list(), reference_variable, transformer_identity(), transformer_undefined, and transformer_undefined_p.

Referenced by any_assign_to_transformer(), any_expressions_to_transformer(), assign_rhs_to_reflhs_to_transformer(), complete_forloop_transformer(), complete_forloop_transformer_list(), condition_to_transformer(), conditional_to_transformer(), dimensions_to_transformer(), expression_to_transformer(), expressions_to_transformer(), forloop_to_postcondition(), forloop_to_transformer(), and struct_reference_assignment_or_equality_to_transformer().

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

◆ safe_integer_expression_to_transformer()

transformer safe_integer_expression_to_transformer ( entity  v,
expression  expr,
transformer  pre,
bool  is_internal 
)

Always return a defined transformer, using effects in case a more precise analysis fails.

Do check wrt to value mappings... if you are not dealing with interprocedural issues

Parameters
exprxpr
prere
is_internals_internal

Definition at line 3552 of file expression.c.

3558 {
3559  transformer tf = integer_expression_to_transformer(v, expr, pre, is_internal);
3560 
3561  if(transformer_undefined_p(tf))
3563 
3564  return tf;
3565 }

References expression_effects_to_transformer(), integer_expression_to_transformer(), and transformer_undefined_p.

Referenced by expression_multiply_sizeof_to_transformer(), integer_binary_operation_to_transformer(), integer_left_shift_to_transformer(), integer_multiply_to_transformer(), loop_to_enter_transformer(), and transformer_add_condition_information_updown().

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

◆ semantics_basic_tag()

static int semantics_basic_tag ( basic  b)
static

Assimilate enum and logical to int (used when they appear in logical operations)

FI: Might be useful quite often in semantics... but forces the programmer to use tags of basic instead of basic variables.

Definition at line 4670 of file expression.c.

4671 {
4672  int t = basic_tag(b);
4673 
4674  if(t==is_basic_derived) {
4675  entity d = basic_derived(b);
4676  type dt = entity_type(d);
4677  if(type_enum_p(dt))
4678  t = is_basic_int;
4679  }
4680  else if(t==is_basic_logical)
4681  t = is_basic_int;
4682 
4683  return t;
4684 }

References basic_derived, basic_tag, entity_type, is_basic_derived, is_basic_int, is_basic_logical, and type_enum_p.

Referenced by transformer_add_any_relation_information().

+ Here is the caller graph for this function:

◆ semantics_usable_points_to_reference_p()

bool semantics_usable_points_to_reference_p ( reference  rlhs,
expression  lhs,
int  n 
)

See if references rlhs is usable and process null, undefined and anywhere locations defined by rlhs.

Expression lhs is passed to clarify the error and warning messages.

n is the number of alternative references. It is used to check the severity of unusable references. If n=1, a NULL rlhs implies a bug. If n>1, the points-to analysis could not determine precisely the target location.

This function is designed to check constant references in a loop over a list of references returned by the points-to analysis.

A heap location may represent several locations. p==heap ^ q==heap does not imply p==q

An anywhere location may represent several locations. p==heap ^ q==heap does not imply p==q

Parameters
rlhslhs
lhshs

Definition at line 6194 of file expression.c.

6195 {
6196  bool usable_p = false;
6197  entity source_lhs = reference_variable(rlhs);
6198  string lhss = expression_undefined_p(lhs)?
6200 
6201  ifdebug(7) {
6202  pips_debug(7, "source reference : %s\n", reference_to_string(rlhs));
6203  }
6204 
6205  if (entity_null_locations_p(source_lhs)) {
6206  if (n == 1)
6207  // An empty transformer should be returned...
6208  pips_user_error("The pointer expression \"%s\" always points to NULL\n",
6209  lhss);
6210  else
6211  semantics_user_warning("The pointer \"%s\" can point to NULL\n",
6212  lhss);
6213  }
6214  else if (entity_typed_nowhere_locations_p(source_lhs)) {
6215  if (n == 1)
6216  pips_user_error("The pointer expression \"%s\" always points to undefined/indeterminate (%s)\n", lhss, reference_to_string(rlhs));
6217  else {
6218  semantics_user_warning("The pointer expression \"%s\" can point to undefined/indeterminate (%s)\n", lhss, reference_to_string(rlhs));
6219  }
6220  }
6221  else if(entity_heap_location_p(source_lhs)) {
6222  // entity_all_heap_locations_p()
6223  // entity_all_module_heap_locations_p()
6224  // entity_all_module_heap_locations_typed : the predicate does not seem to exist
6225  /* A heap location may represent several locations. p==heap ^
6226  q==heap does not imply p==q */
6227  usable_p = false;
6228  }
6229  else if(entity_anywhere_locations_p(source_lhs)
6230  || entity_typed_anywhere_locations_p(source_lhs)) {
6231  /* An anywhere location may represent several locations. p==heap ^
6232  q==heap does not imply p==q */
6233  usable_p = false;
6234  }
6235  else {
6236  // usable_p = atomic_points_to_reference_p(rlhs);
6238  usable_p = analyzed_type_p(t)
6240  }
6241 
6242  ifdebug(7) {
6243  pips_debug(7, "source reference \"%s\" is %s\n", reference_to_string(rlhs),
6244  usable_p ? "usable" : "not usable");
6245  }
6246 
6247  return usable_p;
6248 }
bool entity_heap_location_p(entity b)
package abstract location.
bool entity_typed_anywhere_locations_p(entity e)
Test if an entity is the bottom of the lattice.
bool entity_anywhere_locations_p(entity e)
test if an entity is the bottom of the lattice
bool type_struct_variable_p(type)
Definition: type.c:3867
#define expression_undefined_p(x)
Definition: ri.h:1224

References analyzed_type_p(), entity_anywhere_locations_p(), entity_heap_location_p(), entity_null_locations_p(), entity_typed_anywhere_locations_p(), entity_typed_nowhere_locations_p(), expression_to_string(), expression_undefined_p, ifdebug, pips_debug, pips_user_error, points_to_reference_to_concrete_type(), reference_to_string(), reference_variable, semantics_user_warning, type_struct_variable_p(), and type_variable_p.

Referenced by any_assign_to_transformer(), generic_unary_operation_to_transformer(), lhs_expression_to_transformer(), new_array_elements_backward_substitution_in_transformer(), new_array_elements_forward_substitution_in_transformer(), and struct_reference_assignment_or_equality_to_transformer().

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

◆ simple_affine_to_transformer()

transformer simple_affine_to_transformer ( entity  e,
Pvecteur  a,
bool  is_internal 
)

INTEGER EXPRESSIONS.

FI: I do no longer understand the semantics of "is_internal"... although I designed it. The intent was probably to manage temporary values: they should be preserved as long as the analysis is internal and else projected.

Furthermore, this function is no longer very useful as normalization can be performed dynamically again and again at a low cost.

The renaming from variables in a to new values in ve and vexpr is performed as a side-effect by value_mappings_compatible_vector_p() which fails when a renaming fails.

This is very dangerous when is_internal==false

Parameters
is_internals_internal

Definition at line 1167 of file expression.c.

1168 {
1170  Pvecteur ve = vect_new((Variable) e, VALUE_ONE);
1171  Pvecteur vexpr = vect_dup(a);
1172  Pcontrainte c;
1174 
1175  pips_debug(8, "begin with is_internal=%s\n", bool_to_string(is_internal));
1176 
1177  ifdebug(9) {
1178  pips_debug(9, "\nLinearized expression:\n");
1179  vect_dump(vexpr);
1180  }
1181 
1182  /* The renaming from variables in a to new values in ve and vexpr is
1183  * performed as a side-effect by
1184  * value_mappings_compatible_vector_p() which fails when a
1185  * renaming fails.
1186  *
1187  * This is very dangerous when is_internal==false
1188  */
1189  if(!is_internal
1192  eq = vect_substract(ve, vexpr);
1193  vect_rm(ve);
1194  vect_rm(vexpr);
1195  c = contrainte_make(eq);
1196  tf = make_transformer(NIL,
1198  }
1199  else {
1200  vect_rm(eq);
1201  vect_rm(ve);
1202  vect_rm(vexpr);
1203  tf = transformer_undefined;
1204  }
1205 
1206  pips_debug(8, "end with tf=%p\n", tf);
1207  ifdebug(8) dump_transformer(tf);
1208 
1209  return tf;
1210 }

References bool_to_string(), contrainte_make(), CONTRAINTE_UNDEFINED, dump_transformer, eq, ifdebug, make_predicate(), make_transformer(), NIL, pips_debug, sc_make(), transformer_undefined, value_mappings_compatible_vector_p(), VALUE_ONE, vect_dump(), vect_dup(), vect_new(), vect_rm(), vect_substract(), and VECTEUR_NUL.

Referenced by integer_expression_to_transformer().

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

◆ simplify_boolean_expression_with_precondition()

int simplify_boolean_expression_with_precondition ( expression  e,
transformer  p 
)

Simplification of bool expressions with precondition.

Expression e is modified, if necessary, by side effect.

The value returned is 1 if the expression e is always true (never false) under condition p, 0 if is the expression is always false (never true), and -1 otherwise.

This function is not used within the semantics library. It is exported for partial_eval and suppress_dead_code or similar passes.

Because of C flexibility, all kinds of "boolean" expressions may arise. Think of the conditional and comma operators, think of all kinds of side effects, think of integer expressions,...

FI: In the short term, I only need to deal with bool operators and, or and not.

Definition at line 6080 of file expression.c.

6082 {
6083  int validity = -1; // unknown
6084  bool done = false;
6086  // We could try the global simplification as in the other case...
6087  syntax s = expression_syntax(e);
6088  call c = syntax_call(s);
6089  entity op = call_function(c);
6090  if(ENTITY_NOT_P(op)) {
6093  if(validity>=0)
6094  validity = 1 - validity;
6095  done = true;
6096  }
6097  else if(ENTITY_OR_P(op)) {
6100  if(v1==1)
6101  validity = 1;
6102  else {
6105  if(v2==1)
6106  validity = 1;
6107  else if(v2==0) { // a2 has no impact
6108  if(v1==0)
6109  validity = 0;
6110  else {
6111  validity = -1;
6113  }
6114  }
6115  else // v2==-1
6116  if(v1==0) { // a1 has no impact
6117  validity = -1;
6119  }
6120  else
6121  validity = -1;
6122  }
6123  done =true;
6124  }
6125  else if(ENTITY_AND_P(op)) {
6128  if(v1==0)
6129  validity = 0;
6130  else { // v1 == -1 or 1, no conclusion yet
6133  if(v2==0)
6134  validity = 0;
6135  else if(v2==1) {
6136  if(v1==1)
6137  validity = 1;
6138  else { // get rid of a2
6139  validity = -1;
6141  }
6142  }
6143  else { // v2==-1
6144  if(v1==1) {// a1 is useless
6145  validity = -1;
6147  }
6148  else {
6149  validity = -1;
6150  }
6151  }
6152  }
6153  done =true;
6154  }
6155  }
6156  if (!done) {
6157  transformer tt = condition_to_transformer(e,p, true);
6158  transformer ft = condition_to_transformer(e,p, false);
6159 
6160  if(transformer_empty_p(tt)) {
6161  // Then the condition is always false
6162  validity = 0;
6163  }
6164  if(transformer_empty_p(ft)) {
6165  // Then the condition is always true
6166  validity = 1;
6167  }
6168  // Both can be true simultaneously when the precondition p is
6169  // empty... but it does not matter
6170  }
6171 
6172  if(validity==0||validity==1) {
6173  // e must be replaced by a call to true or false
6176  }
6177 
6178  return validity;
6179 }
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
bool logical_operator_expression_p(expression e)
C xor is missing.
Definition: expression.c:573
expression replace_expression_content(expression e1, expression e2)
Use side effects to move the content of e2, s2 and n2, into e1; s1 and n1 are freed,...
Definition: expression.c:3864
expression make_false_expression()
Definition: expression.c:1108
expression make_true_expression()
Definition: expression.c:1103
int simplify_boolean_expression_with_precondition(expression e, transformer p)
Simplification of bool expressions with precondition.
Definition: expression.c:6080

References call_arguments, call_function, CAR, CDR, condition_to_transformer(), copy_expression(), ENTITY_AND_P, ENTITY_NOT_P, ENTITY_OR_P, EXPRESSION, expression_syntax, logical_operator_expression_p(), make_false_expression(), make_true_expression(), replace_expression_content(), syntax_call, and transformer_empty_p().

+ Here is the call graph for this function:

◆ simplify_minmax_expression()

void simplify_minmax_expression ( expression  e,
transformer  tr 
)

tries hard to simplify expression e if it is a min or a max operator, by evaluating it under preconditions tr.

Two approaches are tested: check bounds of lhs-rhs, or compare bounds of lhs and rhs

Parameters
trr

Definition at line 5849 of file expression.c.

5850 {
5851  if(expression_minmax_p(e)) {
5852  call c =expression_call(e);
5853  bool is_max = ENTITY_MAX_P(call_function(c));
5854 
5855  expression lhs = binary_call_lhs(c);
5856  expression rhs = binary_call_rhs(c);
5857  expression diff = make_op_exp(
5859  copy_expression(lhs),
5860  copy_expression(rhs)
5861  );
5862  intptr_t lhs_lbound,lhs_ubound,rhs_lbound,rhs_ubound,diff_lbound,diff_ubound;
5863  if(precondition_minmax_of_expression(diff,tr,&diff_lbound,&diff_ubound) &&
5864  (diff_lbound>=0 || diff_ubound<=0)) {
5865  if(is_max) {
5866  if(diff_lbound>=0) local_assign_expression(e,lhs);
5867  else local_assign_expression(e,rhs);
5868  }
5869  else {
5870  if(diff_lbound>=0) local_assign_expression(e,rhs);
5871  else local_assign_expression(e,lhs);
5872  }
5873  }
5874  else if(precondition_minmax_of_expression(lhs,tr,&lhs_lbound,&lhs_ubound) &&
5875  precondition_minmax_of_expression(rhs,tr,&rhs_lbound,&rhs_ubound))
5876  {
5877  if(is_max)
5878  {
5879  if(lhs_lbound >=rhs_ubound) local_assign_expression(e,lhs);
5880  else if(rhs_lbound >= lhs_ubound) local_assign_expression(e,rhs);
5881  }
5882  else
5883  {
5884  if(lhs_lbound >=rhs_ubound) local_assign_expression(e,rhs);
5885  else if(rhs_lbound >= lhs_ubound) local_assign_expression(e,lhs);
5886  }
5887  }
5888  }
5889 }
@ is_max
Definition: optimize.c:710
#define binary_call_rhs(c)
#define MINUS_OPERATOR_NAME
#define binary_call_lhs(c)
bool expression_minmax_p(expression e)
Definition: expression.c:3882
void local_assign_expression(expression caller, expression field)
replace expression caller by expression field , where field is contained by caller
Definition: expression.c:3571
expression make_op_exp(char *op_name, expression exp1, expression exp2)
================================================================
Definition: expression.c:2012

References binary_call_lhs, binary_call_rhs, call_function, copy_expression(), ENTITY_MAX_P, expression_call(), expression_minmax_p(), intptr_t, is_max, local_assign_expression(), make_op_exp(), MINUS_OPERATOR_NAME, and precondition_minmax_of_expression().

Referenced by do_array_expansion(), do_solve_hardware_constraints_on_nb_proc(), and region_to_minimal_dimensions().

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

◆ string_expression_to_transformer()

transformer string_expression_to_transformer ( entity  v,
expression  rhs 
)

tf = constant_to_transformer(v, call_function(syntax_call(srhs)));

Parameters
rhshs

Definition at line 3994 of file expression.c.

3996 {
3998  syntax srhs = expression_syntax(rhs);
3999 
4000  switch(syntax_tag(srhs)) {
4001  case is_syntax_call:
4002  switch(gen_length(call_arguments(syntax_call(srhs)))) {
4003  case 0:
4004  /* tf = constant_to_transformer(v, call_function(syntax_call(srhs))); */
4005  tf = constant_to_transformer(v, rhs);
4006  break;
4007  case 1:
4008  break;
4009  case 2:
4010  break;
4011  case 3:
4012  break;
4013  default:
4014  pips_internal_error("Too many arguments, %d, for operator %s",
4017  }
4018  break;
4019  case is_syntax_reference:
4020  {
4022 
4023  if(entity_has_values_p(r)) {
4026 
4027  if(basic_string_p(bv) && basic_string_p(br)) {
4028  int llhs = string_type_size(bv);
4029  int lrhs = string_type_size(br);
4030 
4031  if(llhs == -1 || llhs >= lrhs) {
4032  entity r_new = entity_to_new_value(r);
4033  tf = simple_equality_to_transformer(v, r_new, false);
4034  }
4035  }
4036  else {
4037  pips_user_error("Incompatible type in CHARACTER assignment: %s\n",
4038  basic_to_string(br));
4039  }
4040  }
4041  break;
4042  }
4043  case is_syntax_range:
4044  pips_internal_error("Unexpected tag %d", syntax_tag(srhs));
4045  break;
4046  default:
4047  pips_internal_error("Illegal tag %d", syntax_tag(srhs));
4048  }
4049 
4050  return tf;
4051 }

References basic_string_p, basic_to_string(), call_arguments, call_function, constant_to_transformer(), entity_has_values_p(), entity_name, entity_to_new_value(), entity_type, expression_syntax, gen_length(), is_syntax_call, is_syntax_range, is_syntax_reference, pips_internal_error, pips_user_error, reference_variable, simple_equality_to_transformer(), string_type_size(), syntax_call, syntax_reference, syntax_tag, transformer_undefined, type_variable, and variable_basic.

Referenced by any_expression_to_transformer().

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

◆ transformer_add_anded_conditions_updown()

static transformer transformer_add_anded_conditions_updown ( transformer  pre,
expression  c1,
expression  c2,
transformer  context,
bool  veracity,
bool  upwards 
)
static

FI: this is a bit confusing because of aliasing conditions. The second condition is added after the first one was analyzed and the "and" effect is enforced by side effect

This is equivalent to allocating copies of pre and then computing their intersection.

This is useful when computing transformers in context

use precondition pre and hope than the convex hull won't destroy all information

compute !(c1&&c2) as !c1 || !c2

might be possible to add a convex hull on the initial values as in !upwards

Definition at line 727 of file expression.c.

734 {
736 
737  pips_debug(9,"Begin with pre=%p, veracity=%s, upwards=%s\n,",
738  pre, bool_to_string(veracity),
739  bool_to_string(upwards));
740 
741  if(veracity) {
742  /* FI: this is a bit confusing because of aliasing conditions.
743  * The second condition is added after the first one was analyzed
744  * and the "and" effect is enforced by side effect
745  *
746  * This is equivalent to allocating copies of pre and then computing
747  * their intersection.
748  */
750  ifdebug(9) {
751  pips_debug(9, "pre=%p:\n", pre);
752  dump_transformer(pre);
753  }
754 
756  (pre, c1, context, veracity, upwards);
757 
758  ifdebug(9) {
759  pips_debug(9, "pre1=%p:\n", pre1);
760  dump_transformer(pre1);
761  }
762 
764  (pre1, c2, context, veracity, upwards);
765 
766  ifdebug(9) {
767  pips_debug(9, "newpre=%p:\n", newpre);
768  dump_transformer(newpre);
769  }
770  }
771  else if(!upwards || upwards) { /* This is useful when computing transformers in context */
772  /* use precondition pre and hope than the convex hull won't destroy
773  all information */
774  /* compute !(c1&&c2) as !c1 || !c2 */
775  transformer pre1 = transformer_dup(pre);
776  transformer pre2 = pre;
777 
779  (pre1, c1, context, false, upwards);
781  (pre2, c2, context, false, upwards);
782  newpre = transformer_convex_hull(pre1, pre2);
783 
786  "pre1 =\n");
787  dump_transformer(pre1);
789  "pre2 =\n");
790  dump_transformer(pre2);
792  "newpre =\n");
793  dump_transformer(newpre);
794  }
795  free_transformer(pre1);
796  free_transformer(pre2);
797  }
798  else {
799  /* might be possible to add a convex hull on the initial values
800  * as in !upwards
801  */
802  newpre = pre;
803  }
804 
805  ifdebug(9) {
806  pips_debug(9, "end with newpre=%p\n", newpre);
807  dump_transformer(newpre);
808  }
809 
810  return newpre;
811 }
#define DEBUG_TRANSFORMER_ADD_CONDITION_INFORMATION_UPDOWN
HANDLING OF CONDITIONS.
Definition: expression.c:716

References bool_to_string(), DEBUG_TRANSFORMER_ADD_CONDITION_INFORMATION_UPDOWN, dump_transformer, free_transformer(), ifdebug, pips_debug, transformer_add_condition_information_updown(), transformer_convex_hull(), transformer_dup(), and transformer_undefined.

Referenced by transformer_add_call_condition_information_updown().

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

◆ transformer_add_any_relation_information()

transformer transformer_add_any_relation_information ( transformer  pre,
entity  op,
expression  e1,
expression  e2,
transformer  context,
bool  veracity,
bool  upwards 
)

compute transformer or precondition

This is not satisfactory: when going upwards you might nevertheless benefit from some precondition information. But you would then need to pass two transformers as argument: a context transformer and a to-be-modified transformer

context = upwards? transformer_undefined : pre;

context = transformer_range(pre);

Logical are represented by integer values

PIPS does not represent negative constants: call to unary_minus

PIPS does not represent complex constants: call to CMPLX

Only constant string are processed

Pointer analysis

This is not correct if side effects occur in e1 or e2

This is very complicated to add constraints from tf1, tf2 and rel in pre!

tf1 may modify the initial context. See w10.f

tf1 disappears into cond

try to break rel it into two convex components

pre disappears into newpre2

pre disappears into newpre

newpre stays undefined or newpre is pre

free_transformer(tf1); already gone

Nothing to be done with struct and union

pre may be unchanged when no information is derived

Parameters
prere
opprecondition
e11
e22
contextontext
veracityeracity
upwardsthe relation is true or not

Definition at line 4686 of file expression.c.

4694 {
4697  int t1 = semantics_basic_tag(b1);
4698  int t2 = semantics_basic_tag(b2);
4699 
4700  pips_debug(8, "begin %s with pre=%p\n",
4701  upwards? "upwards" : "downwards", pre);
4702 
4703  /* This is not satisfactory: when going upwards you might nevertheless
4704  benefit from some precondition information. But you would then need
4705  to pass two transformers as argument: a context transformer and a
4706  to-be-modified transformer */
4707 
4708  /* context = upwards? transformer_undefined : pre; */
4709  /* context = transformer_range(pre); */
4710 
4711  if( (t1==t2)
4712  || (t1==is_basic_int && t2==is_basic_string)
4713  || (t2==is_basic_int && t1==is_basic_string) ) {
4714 
4715  switch(t1) {
4716  case is_basic_logical:
4717  /* Logical are represented by integer values*/
4718  case is_basic_float:
4719  /* PIPS does not represent negative constants: call to unary_minus */
4720  case is_basic_complex:
4721  /* PIPS does not represent complex constants: call to CMPLX */
4722  case is_basic_string:
4723  /* Only constant string are processed */
4724  case is_basic_pointer:
4725  /* Pointer analysis */
4726  case is_basic_int:
4727  {
4728  /* This is not correct if side effects occur in e1 or e2 */
4729  /* This is very complicated to add constraints from tf1, tf2 and
4730  rel in pre! */
4734  /* tf1 may modify the initial context. See w10.f */
4736  : transformer_apply(tf1, context);
4737  transformer ncontext = transformer_range(pcontext);
4738  transformer tf2 = safe_any_expression_to_transformer(tmp2, e2, ncontext, true);
4739  // FI: not precise because the context is not taken into
4740  // account when non-convex information is available,
4741  // non-convex information that could be convex within the
4742  // context. But see below.
4743  transformer rel = relation_to_transformer(op, tmp1, tmp2, veracity);
4746 
4747  free_transformer(pcontext);
4748  free_transformer(ncontext);
4749 
4750  /* tf1 disappears into cond */
4751  cond = transformer_safe_combine_with_warnings(tf1, tf2);
4752 
4754  /* try to break rel it into two convex components */
4755  if((ENTITY_NON_EQUAL_P(op) && veracity)
4756  || (ENTITY_EQUAL_P(op) && !veracity)) {
4759  transformer rel1 = relation_to_transformer(lt, tmp1, tmp2, true);
4760  transformer rel2 = relation_to_transformer(gt, tmp1, tmp2, true);
4761  transformer full_cond1 = transformer_safe_image_intersection(cond, rel1);
4762  transformer full_cond2 = transformer_safe_image_intersection(cond, rel2);
4763  /* pre disappears into newpre2 */
4764  transformer newpre1 = transformer_combine(transformer_dup(pre), full_cond1);
4765  transformer newpre2 = transformer_combine(pre, full_cond2);
4766 
4767  free_transformer(rel1);
4768  free_transformer(rel2);
4769 
4770  newpre = transformer_convex_hull(newpre1, newpre2);
4771 
4772  free_transformer(full_cond1);
4773  free_transformer(full_cond2);
4774  free_transformer(newpre1);
4775  free_transformer(newpre2);
4776  }
4777  }
4778  else if (!transformer_undefined_p(cond)){
4779  transformer full_cond = transformer_safe_image_intersection(cond, rel);
4780  /* pre disappears into newpre */
4781  newpre = transformer_combine(pre, full_cond);
4782  free_transformer(full_cond);
4783  }
4784  else {
4785  /* newpre stays undefined or newpre is pre*/
4786  newpre = pre;
4787  }
4788 
4789  transformer_free(cond);
4790  pre = newpre;
4791 
4792  pips_assert("Pre is still consistent with tf1 and tf2 and rel",
4794 
4795  /* free_transformer(tf1); already gone */
4796  free_transformer(tf2);
4797  free_transformer(rel);
4798  break;
4799  }
4800  case is_basic_overloaded:
4801  pips_internal_error("illegal overloaded type for operator %s",
4802  entity_name(op));
4803  break;
4804  case is_basic_bit:
4805  // Do not emit the same message during the second analysis of
4806  // the condition
4807  if(veracity)
4808  semantics_user_warning("bit type not analyzed for operator %s\n",
4809  entity_name(op));
4810  break;
4811 // case is_basic_pointer:
4812 // if(veracity)
4813 // semantics_user_warning("pointer type not analyzed for operator %s\n",
4814 // entity_name(op));
4815 // break;
4816  case is_basic_derived:
4817  /* Nothing to be done with struct and union */
4818  break;
4819  case is_basic_typedef:
4820  pips_internal_error("typedef should ne converted to concrete types for operator %s",
4821  entity_name(op));
4822  break;
4823  default:
4824  pips_internal_error("unknown basic b=%d", basic_tag(b1));
4825  }
4826  }
4827 
4828  free_basic(b1);
4829  free_basic(b2);
4830 
4831  pre = transformer_normalize(pre, 2);
4832 
4833  /* pre may be unchanged when no information is derived */
4834  pips_debug(8, "end with pre=%p\n", pre);
4835 
4836  return pre;
4837 }
bool transformer_argument_consistency_p(transformer t)
Definition: basic.c:551
void transformer_free(transformer t)
Definition: basic.c:68
#define GREATER_THAN_OPERATOR_NAME
#define LESS_THAN_OPERATOR_NAME
entity local_name_to_top_level_entity(const char *n)
This function try to find a top-level entity from a local name.
Definition: entity.c:1450
@ is_basic_bit
Definition: ri.h:577
static int semantics_basic_tag(basic b)
Assimilate enum and logical to int (used when they appear in logical operations)
Definition: expression.c:4670
transformer relation_to_transformer(entity op, entity e1, entity e2, bool veracity)
e and f are assumed to be values.
Definition: transformer.c:139

References b1, b2, basic_of_expression(), basic_tag, ENTITY_EQUAL_P, entity_name, ENTITY_NON_EQUAL_P, free_basic(), free_transformer(), GREATER_THAN_OPERATOR_NAME, is_basic_bit, is_basic_complex, is_basic_derived, is_basic_float, is_basic_int, is_basic_logical, is_basic_overloaded, is_basic_pointer, is_basic_string, is_basic_typedef, LESS_THAN_OPERATOR_NAME, local_name_to_top_level_entity(), make_local_temporary_value_entity_with_basic(), pips_assert, pips_debug, pips_internal_error, relation_to_transformer(), safe_any_expression_to_transformer(), semantics_basic_tag(), semantics_user_warning, transformer_apply(), transformer_argument_consistency_p(), transformer_combine(), transformer_convex_hull(), transformer_dup(), transformer_free(), transformer_identity(), transformer_normalize(), transformer_range(), transformer_safe_combine_with_warnings(), transformer_safe_image_intersection(), transformer_undefined, and transformer_undefined_p.

Referenced by logical_binary_function_to_transformer(), and transformer_add_call_condition_information_updown().

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

◆ transformer_add_call_condition_information_updown()

static transformer transformer_add_call_condition_information_updown ( transformer  pre,
entity  op,
list  args,
transformer  context,
bool  veracity,
bool  upwards 
)
static

do not know what to do with other logical operators, for the time being! keep pre unmodified

FI: two problems, you can bump into arithmetic operators and you can have side effects as in i++

Minimal service: use effects

Definition at line 882 of file expression.c.

889 {
893 
894  pips_debug(9,"Begin with pre=%p, op=%s, veracity=%s, upwards=%s\n,",
895  pre, module_local_name(op), bool_to_string(veracity),
896  bool_to_string(upwards));
897 
898  if(!ENDP(args)) {
899  c1 = EXPRESSION(CAR(args));
900  if(!ENDP(CDR(args))) {
901  c2 = EXPRESSION(CAR(CDR(args)));
902  }
903  }
904 
906  newpre = transformer_add_any_relation_information(pre, op, c1, c2, context,
907  veracity, upwards);
908  }
909  else if(ENTITY_AND_P(op)) {
911  (pre, c1, c2, context, veracity, upwards);
912  }
913  else if(ENTITY_OR_P(op)) {
915  (pre, c1, c2, context, veracity, upwards);
916  }
917  else if(ENTITY_NOT_P(op)) {
919  (pre, c1, context, !veracity, upwards);
920  }
921  else if(((ENTITY_TRUE_P(op) || ENTITY_ONE_P(op)) && !veracity) ||
922  ((ENTITY_FALSE_P(op) || ENTITY_ZERO_P(op)) && veracity)) {
923  free_transformer(pre);
924  newpre = transformer_empty();
925  }
926  else {
927  /* do not know what to do with other logical operators, for the
928  * time being! keep pre unmodified
929  *
930  * FI: two problems, you can bump into arithmetic operators and
931  * you can have side effects as in i++
932  */
933  /* Minimal service: use effects */
934  newpre = pre;
935  FOREACH(EXPRESSION, a, args) {
937  newpre = transformer_combine(tf, newpre);
938  }
939  }
940 
941  ifdebug(9) {
942  pips_debug(9, "end with newpre=%p\n", newpre);
943  dump_transformer(newpre);
944  }
945 
946  return newpre;
947 }
static transformer transformer_add_ored_conditions_updown(transformer pre, expression c1, expression c2, transformer context, bool veracity, bool upwards)
call transformer_add_condition_information_updown() recursively on both sub-expressions if veracity =...
Definition: expression.c:820
static transformer transformer_add_anded_conditions_updown(transformer pre, expression c1, expression c2, transformer context, bool veracity, bool upwards)
Definition: expression.c:727

References bool_to_string(), CAR, CDR, dump_transformer, ENDP, ENTITY_AND_P, ENTITY_FALSE_P, ENTITY_NOT_P, ENTITY_ONE_P, ENTITY_OR_P, ENTITY_RELATIONAL_OPERATOR_P, ENTITY_TRUE_P, ENTITY_ZERO_P, EXPRESSION, expression_effects_to_transformer(), expression_undefined, FOREACH, free_transformer(), ifdebug, module_local_name(), pips_debug, transformer_add_anded_conditions_updown(), transformer_add_any_relation_information(), transformer_add_condition_information_updown(), transformer_add_ored_conditions_updown(), transformer_combine(), transformer_empty(), and transformer_undefined.

Referenced by transformer_add_condition_information_updown().

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

◆ transformer_add_condition_information()

transformer transformer_add_condition_information ( transformer  pre,
expression  c,
transformer  context,
bool  veracity 
)
Parameters
prere
contextontext
veracityeracity

Definition at line 1092 of file expression.c.

1097 {
1098  transformer post =
1100  veracity, true);
1101 
1104 
1105  return post;
1106 }

References reset_temporary_value_counter(), transformer_add_condition_information_updown(), and transformer_temporary_value_projection().

Referenced by check_condition_wrt_precondition(), old_complete_whileloop_transformer(), and transformer_add_domain_condition().

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

◆ transformer_add_condition_information_updown()

static transformer transformer_add_condition_information_updown ( transformer  pre,
expression  c,
transformer  context,
bool  veracity,
bool  upwards 
)
static

call transformer_add_condition_information_updown() recursively on both sub-expressions if veracity == true; else try your best...

Non-convex information can be made convex when moving postcondition downwards because some of the parts introducing non-convexity may be made empty by the pre-existing precondition.

This is not true for transformers computed upwards, although conditions on initial values could also be added. Let's wait for a case which would prove this useful.

Argument pre is modified and may or not be returned as newpre. It may also be freed and newpre allocated. In other words, argument "pre" should not be used after a call to this function and the returned value alswayd used.

default option: no condition can be added

A logical variable must be referenced in Fortran. Any variable can be referenced in C.

information may be lost

ignore cast (should be a boolean cast...)

Definition at line 961 of file expression.c.

967 {
968  /* default option: no condition can be added */
969  transformer newpre = pre;
970  syntax s = expression_syntax(c);
971 
974  "begin upwards=%s veracity=%s c=",
975  bool_to_string(upwards), bool_to_string(veracity));
976  print_expression(c);
977  (void) fprintf(stderr,"pre=%p\n", pre);
978  dump_transformer(pre);
979  (void) fprintf(stderr,"and context=%p\n", context);
981  }
982 
983  switch(syntax_tag(s)){
984  case is_syntax_call:
985  {
987  // FI: for the time being, I do not use ultimate_type()
990  if(basic_overloaded_p(cb)) {
991  type ert = expression_to_type(c);
993  }
994 
996  list args = call_arguments(syntax_call(s));
997 
999  (pre, f, args, context, veracity, upwards);
1000  }
1001  else if(basic_int_p(cb)) {
1002  if(( ENTITY_ONE_P(f) && !veracity) ||
1003  (ENTITY_ZERO_P(f) && veracity)) {
1004  free_transformer(pre);
1005  newpre = transformer_empty();
1006  }
1007  else {
1009  transformer ct =
1011  if(!veracity)
1013  newpre = transformer_apply(ct, pre);
1014  free_transformer(ct);
1015  free_transformer(pre);
1016  }
1017  }
1018  else {
1020  newpre = transformer_apply(tf, pre);
1021  free_transformer(tf);
1022  free_transformer(pre);
1023  }
1024  free_basic(cb);
1025  break;
1026  }
1027  case is_syntax_reference:
1028  {
1029  /* A logical variable must be referenced in Fortran. Any
1030  variable can be referenced in C. */
1032  if(entity_has_values_p(l)) {
1033  entity l_new = entity_to_new_value(l);
1034  type lt = ultimate_type(entity_type(l));
1036 
1037  if(basic_logical_p(lb)) {
1038  Pvecteur eq = vect_new((Variable) l_new, VALUE_ONE);
1039 
1040  if(veracity) {
1042  }
1043 
1044  newpre = transformer_equality_add(pre, eq);
1045  }
1046  else {
1047  Pvecteur eq = vect_new((Variable) l_new, VALUE_ONE);
1048 
1049  if(veracity) {
1052  }
1053  newpre = transformer_inequality_add(pre, eq);
1054  }
1055  }
1056  break;
1057  }
1058  case is_syntax_range:
1059  {
1060  pips_internal_error("range used as test condition!");
1061  break;
1062  }
1063  case is_syntax_subscript:
1064  {
1065  /* information may be lost */
1066  newpre = pre;
1067  break;
1068  }
1069  case is_syntax_cast:
1070  {
1071  /* ignore cast (should be a boolean cast...) */
1072  cast cce = syntax_cast(s);
1073  expression ce = cast_expression(cce);
1074  newpre =
1076  veracity, upwards);
1077  break;
1078  }
1079  default:
1080  pips_internal_error("ill. expr. as test condition");
1081  }
1082 
1085  "end newpre=%p\n", newpre);
1086  dump_transformer(newpre);
1087  }
1088 
1089  return newpre;
1090 }
#define functional_result(x)
Definition: ri.h:1444
#define type_functional(x)
Definition: ri.h:2952
static transformer transformer_add_call_condition_information_updown(transformer pre, entity op, list args, transformer context, bool veracity, bool upwards)
Definition: expression.c:882

References basic_int_p, basic_logical_p, basic_overloaded_p, bool_to_string(), call_arguments, call_function, cast_expression, copy_basic(), DEBUG_TRANSFORMER_ADD_CONDITION_INFORMATION_UPDOWN, dump_transformer, ENTITY_FALSE_P, entity_has_values_p(), ENTITY_LOGICAL_OPERATOR_P, ENTITY_ONE_P, entity_to_new_value(), ENTITY_TRUE_P, entity_type, ENTITY_ZERO_P, eq, expression_effects_to_transformer(), expression_syntax, expression_to_type(), f(), fprintf(), free_basic(), free_transformer(), functional_result, ifdebug, is_syntax_call, is_syntax_cast, is_syntax_range, is_syntax_reference, is_syntax_subscript, make_local_temporary_integer_value_entity(), pips_debug, pips_internal_error, print_expression(), reference_variable, safe_integer_expression_to_transformer(), syntax_call, syntax_cast, syntax_reference, syntax_tag, TCST, transformer_add_call_condition_information_updown(), transformer_add_equality_with_integer_constant(), transformer_apply(), transformer_empty(), transformer_equality_add(), transformer_inequality_add(), type_functional, type_variable, ultimate_type(), VALUE_MONE, VALUE_ONE, variable_basic, vect_add_elem(), vect_multiply(), and vect_new().

Referenced by condition_to_transformer(), precondition_add_condition_information(), transformer_add_anded_conditions_updown(), transformer_add_call_condition_information_updown(), transformer_add_condition_information(), and transformer_add_ored_conditions_updown().

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

◆ transformer_add_domain_condition()

transformer transformer_add_domain_condition ( transformer  tf,
expression  c,
transformer  context,
bool  veracity 
)
Parameters
tff
contextontext
veracityeracity

Definition at line 1138 of file expression.c.

1142 {
1143  tf = transformer_add_condition_information(tf, c, context, veracity);
1144  return tf;
1145 }
transformer transformer_add_condition_information(transformer pre, expression c, transformer context, bool veracity)
Definition: expression.c:1092

References transformer_add_condition_information().

Referenced by test_to_total_precondition().

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

◆ transformer_add_integer_relation_information()

transformer transformer_add_integer_relation_information ( transformer  pre,
entity  relop,
expression  e1,
expression  e2,
bool  veracity,
bool  upwards 
)

It is supposed to be obsolete but is still called.

Maybe, it's only partly obsolete... If upwards is false, it is worth performing more convex hulls because the precondition on entry may restrain the space. upwards = transformer, !upwards = precondition

default: no change

both expressions e1 and e2 must be affine

Make sure that new values only are used in v1 and v2

v1 - v2 == 0

v2 - v1 + 1 <= 0 ou v1 - v2 + 1 <= 0

FI: I do not know if this is valid when your are moving upwards variables in v2 and v1 may have to be renamed as init values (i.e. old values)

FI: I think that this should be programmed (see comment above) but I'm waiting for a bug to occur... (6 July 1993)

FI: Well, the bug was eventually seen:-) (8 November 1995)

free_transformer(prea);

free_transformer(preb);

v2 - v1 + 1 <= 0

v1 - v2 <= 0

v2 - v1 <= 0

v1 - v2 + 1 <= 0

do nothing... although Malik may have tried harder!

do nothing, although MODULO and INTEGER DIVIDE could be handled

Parameters
prere
relopelop
e11
e22
veracityeracity
upwardspwards

Definition at line 5929 of file expression.c.

5936 {
5937 # define DEBUG_TRANSFORMER_ADD_RELATION_INFORMATION 7
5938  /* default: no change */
5939  transformer newpre = pre;
5940  /* both expressions e1 and e2 must be affine */
5943 
5946  "begin upwards=%s veracity=%s relop=%s e1=",
5947  bool_to_string(upwards), bool_to_string(veracity),
5948  entity_local_name(relop));
5949  print_expression(e1);
5950  (void) fprintf(stderr,"e2=");
5951  print_expression(e2);
5952  (void) fprintf(stderr,"pre=");
5953  print_transformer(pre);
5954  }
5955 
5961 
5962  /* Make sure that new values only are used in v1 and v2 */
5965 
5966  if((ENTITY_EQUAL_P(relop) && veracity) ||
5967  (ENTITY_NON_EQUAL_P(relop) && !veracity)) {
5968  /* v1 - v2 == 0 */
5969  Pvecteur v = vect_substract(v1, v2);
5970  if(upwards) {
5971  upwards_vect_rename(v, pre);
5972  }
5973  newpre = transformer_equality_add(pre, v);
5974  }
5975  else if((ENTITY_EQUAL_P(relop) && !veracity) ||
5976  (ENTITY_NON_EQUAL_P(relop) && veracity)) {
5977  /* v2 - v1 + 1 <= 0 ou v1 - v2 + 1 <= 0 */
5978  /* FI: I do not know if this is valid when your are moving upwards
5979  * variables in v2 and v1 may have to be renamed as #init values (i.e. old values)
5980  */
5981  transformer prea = transformer_dup(pre);
5982  transformer preb = pre;
5983  Pvecteur va = vect_substract(v2, v1);
5984  Pvecteur vb = vect_substract(v1, v2);
5985  vect_add_elem(&va, TCST, VALUE_ONE);
5986  vect_add_elem(&vb, TCST, VALUE_ONE);
5987  /* FI: I think that this should be programmed (see comment above)
5988  * but I'm waiting for a bug to occur... (6 July 1993)
5989  *
5990  * FI: Well, the bug was eventually seen:-) (8 November 1995)
5991  */
5992  if(upwards) {
5993  upwards_vect_rename(va, pre);
5994  upwards_vect_rename(vb, pre);
5995  }
5996  prea = transformer_inequality_add(prea, va);
5997  preb = transformer_inequality_add(preb, vb);
5998  newpre = transformer_convex_hull(prea, preb);
5999  /* free_transformer(prea); */
6000  /* free_transformer(preb); */
6001  }
6002  else if ((ENTITY_GREATER_THAN_P(relop) && veracity) ||
6003  (ENTITY_LESS_OR_EQUAL_P(relop) && !veracity)) {
6004  /* v2 - v1 + 1 <= 0 */
6005  Pvecteur v = vect_substract(v2, v1);
6007  if(upwards) {
6008  upwards_vect_rename(v, pre);
6009  }
6010  newpre = transformer_inequality_add(pre, v);
6011  }
6012  else if ((ENTITY_GREATER_THAN_P(relop) && !veracity) ||
6013  (ENTITY_LESS_OR_EQUAL_P(relop) && veracity)) {
6014  /* v1 - v2 <= 0 */
6015  Pvecteur v = vect_substract(v1, v2);
6016  if(upwards) {
6017  upwards_vect_rename(v, pre);
6018  }
6019  newpre = transformer_inequality_add(pre, v);
6020  }
6021  else if ((ENTITY_GREATER_OR_EQUAL_P(relop) && veracity) ||
6022  (ENTITY_LESS_THAN_P(relop) && !veracity)) {
6023  /* v2 - v1 <= 0 */
6024  Pvecteur v = vect_substract(v2, v1);
6025  if(upwards) {
6026  upwards_vect_rename(v, pre);
6027  }
6028  newpre = transformer_inequality_add(pre, v);
6029  }
6030  else if ((ENTITY_GREATER_OR_EQUAL_P(relop) && !veracity) ||
6031  (ENTITY_LESS_THAN_P(relop) && veracity)) {
6032  /* v1 - v2 + 1 <= 0 */
6033  Pvecteur v = vect_substract(v1, v2);
6035  if(upwards) {
6036  upwards_vect_rename(v, pre);
6037  }
6038  newpre = transformer_inequality_add(pre, v);
6039  }
6040  else {
6041  /* do nothing... although Malik may have tried harder! */
6042  newpre = pre;
6043  }
6044  vect_rm(v1);
6045  vect_rm(v2);
6046  }
6047  else
6048  /* do nothing, although MODULO and INTEGER DIVIDE could be handled */
6049  newpre = pre;
6050 
6053  "end newpre=\n");
6054  print_transformer(newpre);
6055  pips_assert("Transformer is internally consistent",
6057  }
6058 
6059  return newpre;
6060 }
bool transformer_internal_consistency_p(transformer t)
Same as above but equivalenced variables should not appear in the argument list or in the predicate b...
Definition: basic.c:790
#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 DEBUG_TRANSFORMER_ADD_RELATION_INFORMATION
void variables_to_new_values(Pvecteur v)
replace variables by new values which is necessary for equivalenced variables
Definition: mappings.c:1038
void upwards_vect_rename(Pvecteur v, transformer post)
Renaming of variables in v according to transformations occuring later.
Definition: mappings.c:1062

References bool_to_string(), DEBUG_TRANSFORMER_ADD_RELATION_INFORMATION, 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_NON_EQUAL_P, fprintf(), ifdebug, NORMALIZE_EXPRESSION, normalized_linear, normalized_linear_p, pips_assert, pips_debug, print_expression(), print_transformer, TCST, transformer_convex_hull(), transformer_dup(), transformer_equality_add(), transformer_inequality_add(), transformer_internal_consistency_p(), upwards_vect_rename(), value_mappings_compatible_vector_p(), VALUE_ONE, variables_to_new_values(), vect_add_elem(), vect_dup(), vect_rm(), and vect_substract().

+ Here is the call graph for this function:

◆ transformer_add_ored_conditions_updown()

static transformer transformer_add_ored_conditions_updown ( transformer  pre,
expression  c1,
expression  c2,
transformer  context,
bool  veracity,
bool  upwards 
)
static

call transformer_add_condition_information_updown() recursively on both sub-expressions if veracity == false; else try to do your best...

Should be fused with the .AND. case?!? Careful with veracity...

compute !(c1||c2) as !c1 && !c2

compute (c1||c2) as such

might be possible to add a convex hull on the initial values as in !upwards

Definition at line 820 of file expression.c.

827 {
829 
830  pips_debug(9,"Begin with pre=%p, context=%p, veracity=%s, upwards=%s\n,",
831  pre, context, bool_to_string(veracity),
832  bool_to_string(upwards));
833 
834  if(!veracity) {
835  /* compute !(c1||c2) as !c1 && !c2 */
837  (pre, c1, context, false, upwards);
839  (newpre, c2, context, false, upwards);
840  }
841  else if(!upwards) {
842  /* compute (c1||c2) as such */
843  transformer pre1 = transformer_dup(pre);
844  transformer pre2 = pre;
845 
847  (pre1, c1, context, true, upwards);
849  (pre2, c2, context, true, upwards);
850  newpre = transformer_convex_hull(pre1, pre2);
851 
854  "pre1 =\n");
855  (void) (void) dump_transformer(pre1);
857  "pre2 =\n");
858  (void) dump_transformer(pre2);
860  "newpre =\n");
861  (void) (void) dump_transformer(newpre);
862  }
863 
864  free_transformer(pre1);
865  free_transformer(pre2);
866  }
867  else {
868  /* might be possible to add a convex hull on the initial values
869  * as in !upwards
870  */
871  newpre = pre;
872  }
873 
874  ifdebug(9) {
875  pips_debug(9, "end with newpre=%p\n", newpre);
876  dump_transformer(newpre);
877  }
878 
879  return newpre;
880 }

References bool_to_string(), DEBUG_TRANSFORMER_ADD_CONDITION_INFORMATION_UPDOWN, dump_transformer, free_transformer(), ifdebug, pips_debug, transformer_add_condition_information_updown(), transformer_convex_hull(), transformer_dup(), and transformer_undefined.

Referenced by transformer_add_call_condition_information_updown().

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

◆ transformer_add_range_condition()

transformer transformer_add_range_condition ( transformer  tf,
expression  c,
transformer  context,
bool  veracity 
)
Parameters
tff
contextontext
veracityeracity

Definition at line 1147 of file expression.c.

1151 {
1152  tf = precondition_add_condition_information(tf, c, context, veracity);
1153  return tf;
1154 }

References precondition_add_condition_information().

+ Here is the call graph for this function:

◆ transformer_logical_inequalities_add()

transformer transformer_logical_inequalities_add ( transformer  tf,
entity  v 
)

PROCESSING OF LOGICAL EXPRESSIONS.

the values of v are between 0 and 1

Parameters
tff

Definition at line 3569 of file expression.c.

3570 {
3571  /* the values of v are between 0 and 1 */
3572  Pvecteur ineq1 = vect_new((Variable) v, VALUE_ONE);
3573  Pvecteur ineq2 = vect_new((Variable) v, VALUE_MONE);
3574 
3575  vect_add_elem(&ineq1, TCST, VALUE_MONE);
3576 
3577  tf = transformer_inequality_add(tf, ineq1);
3578  tf = transformer_inequality_add(tf, ineq2);
3579 
3580  return tf;
3581 }

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

Referenced by logical_binary_operation_to_transformer(), logical_reference_to_transformer(), and logical_unary_operation_to_transformer().

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

◆ true_condition_wrt_precondition_p()

bool true_condition_wrt_precondition_p ( expression  c,
transformer  pre 
)
Parameters
prere

Definition at line 5900 of file expression.c.

5901 {
5902  bool result = false;
5903 
5904  result = eval_condition_wrt_precondition_p(c, pre, true);
5905 
5906  return result;
5907 }

References eval_condition_wrt_precondition_p().

Referenced by whileloop_to_postcondition(), and whileloop_to_total_precondition().

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

◆ unary_minus_operation_to_transformer()

static transformer unary_minus_operation_to_transformer ( entity  v,
expression  e1,
transformer  pre,
bool  is_internal 
)
static

Type independent.

Most of it should be factored out for unary operations.

sub-expressions are not necessarily integer? Then the expression should not be integer?

Much too early: you are in between recursive calls!

tf = transformer_temporary_value_projection(tf);

Definition at line 288 of file expression.c.

292 {
295  /* sub-expressions are not necessarily integer? Then the expression
296  should not be integer? */
297  transformer tf1 = any_expression_to_transformer(tmp1, e1, pre, is_internal);
299 
300  pips_debug(9, "Begin for %s\n", entity_local_name(v));
301 
302  tf = transformer_safe_intersection(tf1, tf_op);
303 
304  /* Much too early: you are in between recursive calls! */
305  /* tf = transformer_temporary_value_projection(tf); */
306 
307  free_transformer(tf1);
308  free_transformer(tf_op);
309 
310  pips_debug(9, "End with %p\n", tf);
311  ifdebug(9) dump_transformer(tf);
312 
313  return tf;
314 }
transformer simple_unary_minus_to_transformer(entity e, entity f)
Definition: transformer.c:65

References any_expression_to_transformer(), dump_transformer, entity_local_name(), entity_type, free_transformer(), ifdebug, make_local_temporary_value_entity(), pips_debug, simple_unary_minus_to_transformer(), transformer_safe_intersection(), and transformer_undefined.

Referenced by generic_unary_operation_to_transformer(), and pointer_unary_operation_to_transformer().

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

◆ update_operation_to_transformer()

static transformer update_operation_to_transformer ( entity  v,
entity  op,
expression  e1,
expression  e2,
transformer  pre,
bool  is_internal 
)
static

v = (e1 = e1 op e2) ; e1 must be a reference; does not compute information for dereferenced pointers such as in "*p += 2;"

sub-expressions are not necessarily integer? Then the expression should not be integer?

We assume that the update operation is syntactically correct

Effects are used at a higher level

ef,

Too early: you are projecting v and loosing all useful information within an expression!

tf = transformer_temporary_value_projection(tf);

Definition at line 590 of file expression.c.

596 {
598 
599  if(expression_reference_p(e1)) {
600  //transformer utf = transformer_undefined;
603  /* sub-expressions are not necessarily integer? Then the expression
604  should not be integer? */
605  /* We assume that the update operation is syntactically correct */
609  list args = CONS(EXPRESSION, e1, CONS(EXPRESSION, n_exp, NIL));
610 
611  pips_debug(9, "Begin officialy... but a lot has been done already!\n");
612 
613  /* Effects are used at a higher level */
614  tf = any_assign_operation_to_transformer(v, args, /* ef,*/ pre, is_internal);
615  gen_free_list(args);
616  free_expression(n_exp);
617 
618  if(!transformer_undefined_p(tf))
619  tf = transformer_add_equality(tf, v, v1);
620 
621  ifdebug(8) {
622  pips_debug(8, "before projection, with temporaries v=%s, tmp1=%s, tmp2=%s,"
623  " transformer rf=%p\n",
625  entity_local_name(tmp2), tf);
626  dump_transformer(tf);
627  }
628 
629  /* Too early: you are projecting v and loosing all useful information
630  within an expression! */
631  /* tf = transformer_temporary_value_projection(tf); */
632 
633  //free_transformer(tf2);
634  //free_transformer(tf12);
635  //free_transformer(tf12u);
636  //free_transformer(tf_op);
637  }
638 
639  pips_debug(8, "End with transformer tf=%p\n", tf);
640  ifdebug(8) dump_transformer(tf);
641 
642  return tf;
643 }
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
entity update_operator_to_regular_operator(entity op)
Returns the binary operator associated to a C update operator such as +=.
Definition: entity.c:2154

References any_assign_operation_to_transformer(), CONS, copy_expression(), dump_transformer, entity_local_name(), entity_type, EXPRESSION, expression_reference_p(), expression_syntax, free_expression(), gen_free_list(), ifdebug, make_local_temporary_value_entity(), MakeBinaryCall(), NIL, pips_debug, reference_variable, syntax_reference, transformer_add_equality(), transformer_undefined, transformer_undefined_p, and update_operator_to_regular_operator().

Referenced by integer_binary_operation_to_transformer().

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