PIPS
eval.c File Reference
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "linear.h"
#include "genC.h"
#include "ri.h"
#include "misc.h"
#include "ri-util.h"
#include "properties.h"
#include "operator.h"
+ Include dependency graph for eval.c:

Go to the source code of this file.

Functions

value EvalExpression (expression e)
 Evaluate statically an expression. More...
 
value EvalSyntax (syntax s)
 
value EvalCall (call c)
 only calls to constant, symbolic or intrinsic functions might be evaluated. More...
 
value EvalSizeofexpression (sizeofexpression soe)
 
value EvalConstant (constant c)
 Constant c is returned as field of value v. More...
 
value EvalIntrinsic (entity e, list la)
 This function tries to evaluate a call to an intrinsic function. More...
 
value EvalConditionalOp (list la)
 
value EvalUnaryOp (int t, list la)
 
value EvalBinaryOp (int t, list la)
 t defines the operator and la is a list to two sub-expressions. More...
 
value EvalNaryOp (int t, list la)
 
int IsUnaryOperator (entity e)
 
int IsBinaryOperator (entity e)
 FI: These string constants are defined in ri-util.h and the tokens in ri-util/operator.h. More...
 
int IsNaryOperator (entity e)
 
int ipow (int vg, int vd)
 FI: such a function should exist in Linear/arithmetique. More...
 
bool expression_integer_value (expression e, intptr_t *pval)
 
bool expression_negative_integer_value_p (expression e)
 Return true iff the expression has an integer value known statically and this value is negative. More...
 
bool positive_expression_p (expression e)
 Use constants and type information to decide if the value of sigma(e) is always positive, e.g. More...
 
bool negative_expression_p (expression e)
 Use constants and type information to decide if the value of sigma(e) is always negative, e.g. More...
 
bool expression_linear_p (expression e)
 returns if e is already normalized and linear. More...
 
expression range_to_expression (range r, enum range_to_expression_mode mode)
 computes the distance between the lower bound and the upper bound of the range More...
 
bool range_count (range r, intptr_t *pcount)
 The range count only can be evaluated if the three range expressions are constant and if the increment is non zero. More...
 
static bool vect_const_p (Pvecteur v)
 returns true if v is not NULL and is constant More...
 
Pvecteur vect_product (Pvecteur *pv1, Pvecteur *pv2)
 returns a Pvecteur equal to (*pv1) * (*pv2) if this product is linear or NULL otherwise. More...
 
reference constant_reference_to_normalized_constant_reference (reference cr)
 Allocate a new reference with evaluated subscripts. More...
 
expression normalize_integer_constant_expression (expression e)
 Allocate a new expression equivalent to e, but constant expressions are evaluated. More...
 

Function Documentation

◆ constant_reference_to_normalized_constant_reference()

reference constant_reference_to_normalized_constant_reference ( reference  cr)

Allocate a new reference with evaluated subscripts.

For instance, return a[2] for a[10/2-3]

This function deals with all kinds of references, including the points-to references which use fields as subscripts.

There is an ambiguity for a[*] where * may be considered a constant in some passes of PIPS. However, it denotes a constant set of references and not a constant reference. The returned reference is undefined.

Parameters
crr

Definition at line 1068 of file eval.c.

1069 {
1071  list sl = reference_indices(cr);
1072  list nsl = NIL;
1073  bool constant_p = true;
1074  FOREACH(EXPRESSION, s, sl) {
1076  if(unbounded_expression_p(s)) {
1077  constant_p = false;
1078  break;
1079  }
1080  else if(expression_reference_p(s)) {
1081  // it must be a field
1082  ns = copy_expression(s);
1083  }
1084  else {
1085  intptr_t i;
1086  if(expression_integer_value(s, &i)) {
1087  ns = int_to_expression((int) i);
1088  }
1089  else
1090  pips_internal_error("Unexpected case\n.");
1091  }
1092  nsl = CONS(EXPRESSION, ns, nsl);
1093  }
1094  if(constant_p) {
1095  entity v = reference_variable(cr);
1096  ncr = make_reference(v, NIL);
1097  nsl = gen_nreverse(nsl);
1098  reference_indices(ncr) = nsl;
1099  }
1100  else {
1101  gen_full_free_list(nsl);
1102  }
1103  return ncr;
1104 }
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
void gen_full_free_list(list l)
Definition: genClib.c:1023
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define pips_internal_error
Definition: misc-local.h:149
static bool constant_p(entity e)
This function return a bool indicating if related entity e represents a constant.
bool expression_integer_value(expression e, intptr_t *pval)
Definition: eval.c:792
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
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
bool unbounded_expression_p(expression e)
Definition: expression.c:4329
#define reference_undefined
Definition: ri.h:2302
#define reference_variable(x)
Definition: ri.h:2326
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define expression_undefined
Definition: ri.h:1223
#define reference_indices(x)
Definition: ri.h:2328
#define intptr_t
Definition: stdint.in.h:294
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References CONS, constant_p(), copy_expression(), EXPRESSION, expression_integer_value(), expression_reference_p(), expression_undefined, FOREACH, gen_full_free_list(), gen_nreverse(), int_to_expression(), intptr_t, make_reference(), NIL, pips_internal_error, reference_indices, reference_undefined, reference_variable, and unbounded_expression_p().

Referenced by constant_memory_access_path_to_location_entity(), and make_location_entity().

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

◆ EvalBinaryOp()

value EvalBinaryOp ( int  t,
list  la 
)

t defines the operator and la is a list to two sub-expressions.

Integer and floatint point constants are evaluated.

FI: lazy...

OK for Fortran Logical? Int value or logical value?

Parameters
laa

Definition at line 385 of file eval.c.

386 {
387  value v;
388  long long int i_arg_l = 0, i_arg_r = 0;
389  double f_arg_l, f_arg_r;
390  bool int_p = true;
391 
392  pips_assert("non empty list", la != NIL);
393 
394  v = EvalExpression(EXPRESSION(CAR(la)));
396  i_arg_l = constant_int(value_constant(v));
397  f_arg_l = i_arg_l;
398  free_value(v);
399  }
400  else if (value_constant_p(v) && constant_float_p(value_constant(v))) {
401  int_p = false;
402  f_arg_l = constant_float(value_constant(v));
403  }
404  else
405  return v;
406 
407  la = CDR(la);
408 
409  pips_assert("non empty list", la != NIL);
410  v = EvalExpression(EXPRESSION(CAR(la)));
411 
413  i_arg_r = constant_int(value_constant(v));
414  f_arg_r = i_arg_r;
415  }
416  else if (value_constant_p(v) && constant_float_p(value_constant(v))) {
417  f_arg_r = constant_float(value_constant(v));
418  int_p = false;
419  }
420  else
421  return v;
422 
423  switch (t) {
424  case MINUS:
425  if(int_p)
426  constant_int(value_constant(v)) = i_arg_l-i_arg_r;
427  else
428  constant_float(value_constant(v)) = i_arg_l-i_arg_r;
429  break;
430  case PLUS:
431  if(int_p)
432  constant_int(value_constant(v)) = i_arg_l+i_arg_r;
433  else
434  constant_float(value_constant(v)) = f_arg_l+f_arg_r;
435  break;
436  case STAR:
437  if(int_p)
438  constant_int(value_constant(v)) = i_arg_l*i_arg_r;
439  else
440  constant_float(value_constant(v)) = f_arg_l*f_arg_r;
441  break;
442  case SLASH:
443  if(int_p) {
444  if (i_arg_r != 0)
445  constant_int(value_constant(v)) = i_arg_l/i_arg_r;
446  else {
447  pips_user_error("[EvalBinaryOp] zero divide\n");
448  }
449  }
450  else {
451  if (f_arg_r != 0)
452  constant_float(value_constant(v)) = f_arg_l/f_arg_r;
453  else {
454  pips_user_error("[EvalBinaryOp] zero divide\n");
455  }
456  }
457  break;
458  case MOD:
459  if(int_p) {
460  if (i_arg_r != 0)
461  constant_int(value_constant(v)) = i_arg_l%i_arg_r;
462  else {
463  pips_user_error("[EvalBinaryOp] zero divide\n");
464  }
465  }
466  else {
467  if (f_arg_r != 0) {
468  free_value(v);
470  }
471  else {
472  pips_user_error("[EvalBinaryOp] zero divide\n");
473  }
474  }
475  break;
476  case POWER:
477  if(int_p) {
478  if (i_arg_r >= 0)
479  constant_int(value_constant(v)) = ipow(i_arg_l,i_arg_r);
480  else {
481  free_value(v);
483  }
484  }
485  else {
486  /* FI: lazy... */
487  free_value(v);
489  }
490  break;
491  /*
492  * Logical operators should return logical values...
493  */
494  case EQ:
495  if(int_p)
496  constant_int(value_constant(v)) = i_arg_l==i_arg_r;
497  else
498  constant_int(value_constant(v)) = f_arg_l==f_arg_r;
499  break;
500  case NE:
501  if(int_p)
502  constant_int(value_constant(v)) = i_arg_l!=i_arg_r;
503  else
504  constant_int(value_constant(v)) = f_arg_l!=f_arg_r;
505  break;
506  case EQV:
507  if(int_p)
508  constant_int(value_constant(v)) = i_arg_l==i_arg_r;
509  else
510  constant_int(value_constant(v)) = f_arg_l==f_arg_r;
511  break;
512  case NEQV:
513  if(int_p)
514  constant_int(value_constant(v)) = i_arg_l!=i_arg_r;
515  else
516  constant_int(value_constant(v)) = f_arg_l!=f_arg_r;
517  break;
518  case GT:
519  if(int_p)
520  constant_int(value_constant(v)) = i_arg_l>i_arg_r;
521  else
522  constant_int(value_constant(v)) = f_arg_l>f_arg_r;
523  break;
524  case LT:
525  if(int_p)
526  constant_int(value_constant(v)) = i_arg_l<i_arg_r;
527  else
528  constant_int(value_constant(v)) = f_arg_l<f_arg_r;
529  break;
530  case GE:
531  if(int_p)
532  constant_int(value_constant(v)) = i_arg_l>=i_arg_r;
533  else
534  constant_int(value_constant(v)) = f_arg_l>=f_arg_r;
535  break;
536  /* OK for Fortran Logical? Int value or logical value? */
537  case OR:
538  if(int_p)
539  constant_int(value_constant(v)) = (i_arg_l!=0)||(i_arg_r!=0);
540  else
541  constant_int(value_constant(v)) = (f_arg_l!=0)||(f_arg_r!=0);
542  break;
543  case AND:
544  if(int_p)
545  constant_int(value_constant(v)) = (i_arg_l!=0)&&(i_arg_r!=0);
546  else
547  constant_int(value_constant(v)) = (f_arg_l!=0)&&(f_arg_r!=0);
548  break;
549  case BITWISE_OR:
550  if(int_p)
551  constant_int(value_constant(v)) = i_arg_l|i_arg_r;
552  else
553  pips_user_error("Bitwise or cannot have floating point arguments\n");
554  break;
555  case BITWISE_AND:
556  if(int_p)
557  constant_int(value_constant(v)) = i_arg_l&i_arg_r;
558  else
559  pips_user_error("Bitwise and cannot have floating point arguments\n");
560  break;
561  case BITWISE_XOR:
562  if(int_p)
563  constant_int(value_constant(v)) = i_arg_l^i_arg_r;
564  else
565  pips_user_error("Bitwise xor cannot have floating point arguments\n");
566  break;
567  case LEFT_SHIFT:
568  if(int_p)
569  constant_int(value_constant(v)) = i_arg_l<<i_arg_r;
570  else {
571  free_value(v);
573  }
574  break;
575  case RIGHT_SHIFT:
576  if(int_p)
577  constant_int(value_constant(v)) = i_arg_l>>i_arg_r;
578  else {
579  free_value(v);
581  }
582  break;
583  default:
584  free_value(v);
586  }
587 
588  return(v);
589 }
value make_value(enum value_utype tag, void *val)
Definition: ri.c:2832
void free_value(value p)
Definition: ri.c:2787
#define OR
Definition: genspec.h:89
#define STAR
Definition: genspec.h:91
#define AND
Definition: genspec.h:88
#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
#define pips_user_error
Definition: misc-local.h:147
#define POWER
Definition: operator.h:46
#define BITWISE_XOR
Definition: operator.h:54
#define LEFT_SHIFT
Definition: operator.h:56
#define GE
Definition: operator.h:34
#define RIGHT_SHIFT
Definition: operator.h:55
#define MINUS
Definition: operator.h:42
#define NE
Definition: operator.h:38
#define NEQV
Definition: operator.h:39
#define BITWISE_AND
Definition: operator.h:52
#define LT
Definition: operator.h:37
#define BITWISE_OR
Definition: operator.h:53
#define GT
Definition: operator.h:35
#define EQ
Definition: operator.h:32
#define MOD
Definition: operator.h:47
#define EQV
Definition: operator.h:33
value EvalExpression(expression e)
Evaluate statically an expression.
Definition: eval.c:108
int ipow(int vg, int vd)
FI: such a function should exist in Linear/arithmetique.
Definition: eval.c:769
#define value_constant(x)
Definition: ri.h:3073
#define constant_float_p(x)
Definition: ri.h:851
#define constant_int(x)
Definition: ri.h:850
@ is_value_unknown
Definition: ri.h:3035
#define value_constant_p(x)
Definition: ri.h:3071
#define constant_int_p(x)
Definition: ri.h:848
#define constant_float(x)
Definition: ri.h:853
#define PLUS
Definition: sc_gram.c:200
#define SLASH

References AND, BITWISE_AND, BITWISE_OR, BITWISE_XOR, CAR, CDR, constant_float, constant_float_p, constant_int, constant_int_p, EQ, EQV, EvalExpression(), EXPRESSION, free_value(), GE, GT, ipow(), is_value_unknown, LEFT_SHIFT, LT, make_value(), MINUS, MOD, NE, NEQV, NIL, OR, pips_assert, pips_user_error, PLUS, POWER, RIGHT_SHIFT, SLASH, STAR, value_constant, and value_constant_p.

Referenced by EvalIntrinsic().

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

◆ EvalCall()

value EvalCall ( call  c)

only calls to constant, symbolic or intrinsic functions might be evaluated.

recall that intrinsic functions are not known.

SG: it may be better not to evaluate symbolic and keep their symbolic name

it might be an intrinsic function

Definition at line 170 of file eval.c.

171 {
172  value vout, vin;
173  entity f;
174 
175  f = call_function(c);
176  vin = entity_initial(f);
177 
178  if (value_undefined_p(vin))
179  pips_internal_error("undefined value for %s", entity_name(f));
180 
181  switch (value_tag(vin)) {
182  case is_value_intrinsic:
183  vout = EvalIntrinsic(f, call_arguments(c));
184  break;
185  case is_value_constant:
186  vout = EvalConstant((value_constant(vin)));
187  break;
188  case is_value_symbolic:
189  /* SG: it may be better not to evaluate symbolic and keep their symbolic name */
190  if(get_bool_property("EVAL_SYMBOLIC_CONSTANT"))
192  else
193  vout = make_value_unknown();
194  break;
195  case is_value_unknown:
196  /* it might be an intrinsic function */
197  vout = EvalIntrinsic(f, call_arguments(c));
198  break;
199  case is_value_code:
200  vout = make_value_unknown();
201  break;
202  default:
203  pips_internal_error("Unexpected default case.");
204  vout = value_undefined;
205  }
206 
207  return vout;
208 }
value make_value_unknown(void)
Definition: ri.c:2847
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
value EvalConstant(constant c)
Constant c is returned as field of value v.
Definition: eval.c:235
value EvalIntrinsic(entity e, list la)
This function tries to evaluate a call to an intrinsic function.
Definition: eval.c:290
#define value_tag(x)
Definition: ri.h:3064
#define value_undefined_p(x)
Definition: ri.h:3017
#define value_undefined
Definition: ri.h:3016
#define call_function(x)
Definition: ri.h:709
#define symbolic_constant(x)
Definition: ri.h:2599
@ is_value_intrinsic
Definition: ri.h:3034
@ is_value_constant
Definition: ri.h:3033
@ is_value_code
Definition: ri.h:3031
@ is_value_symbolic
Definition: ri.h:3032
#define value_symbolic(x)
Definition: ri.h:3070
#define entity_name(x)
Definition: ri.h:2790
#define call_arguments(x)
Definition: ri.h:711
#define entity_initial(x)
Definition: ri.h:2796

References call_arguments, call_function, entity_initial, entity_name, EvalConstant(), EvalIntrinsic(), f(), get_bool_property(), is_value_code, is_value_constant, is_value_intrinsic, is_value_symbolic, is_value_unknown, make_value_unknown(), pips_internal_error, symbolic_constant, value_constant, value_symbolic, value_tag, value_undefined, and value_undefined_p.

Referenced by EvalSyntax().

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

◆ EvalConditionalOp()

value EvalConditionalOp ( list  la)
Parameters
laa

Definition at line 309 of file eval.c.

310 {
311  value vout, v1, v2, v3;
312  _int arg1 = 0, arg2 = 0, arg3 = 0;
313  bool failed = false;
314 
315  pips_assert("Three arguments", gen_length(la)==3);
316 
317  v1 = EvalExpression(EXPRESSION(CAR(la)));
319  arg1 = constant_int(value_constant(v1));
320  else
321  failed = true;
322 
323  v2 = EvalExpression(EXPRESSION(CAR(CDR(la))));
325  arg2 = constant_int(value_constant(v2));
326  else
327  failed = true;
328 
329  v3 = EvalExpression(EXPRESSION(CAR(CDR(CDR(la)))));
331  arg3 = constant_int(value_constant(v3));
332  else
333  failed = true;
334 
335  if(failed)
337  else
339  make_constant(is_constant_int, (void *) (arg1? arg2: arg3)));
340 
341  free_value(v1);
342  free_value(v2);
343  free_value(v3);
344 
345  return vout;
346 }
constant make_constant(enum constant_utype tag, void *val)
Definition: ri.c:406
size_t gen_length(const list l)
Definition: list.c:150
intptr_t _int
_INT
Definition: newgen_types.h:53
@ is_constant_int
Definition: ri.h:817

References CAR, CDR, constant_int, constant_int_p, EvalExpression(), EXPRESSION, free_value(), gen_length(), is_constant_int, is_value_constant, is_value_unknown, make_constant(), make_value(), NIL, pips_assert, value_constant, and value_constant_p.

Referenced by EvalIntrinsic().

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

◆ EvalConstant()

value EvalConstant ( constant  c)

Constant c is returned as field of value v.

Definition at line 235 of file eval.c.

236 {
238 
239  if(constant_int_p(c)) {
242  (void*) constant_int(c)));
243  }
244  else if(constant_float_p(c)) {
246  NULL);
248  v = make_value(is_value_constant, nc);
249  }
250  else if(constant_call_p(c)) {
251  entity e = constant_call(c);
252  type t = entity_type(e);
253  if(type_functional_p(t)) {
255  t = functional_result(f);
256  }
257  if(scalar_integer_type_p(t)) {
258  long long int val;
259  sscanf(entity_local_name(e), "%lld", &val);
262  (void*) val));
263  }
264  else if(float_type_p(t)) {
265  double val;
266  sscanf(entity_local_name(e), "%lg", &val);
268  NULL);
269  constant_float(nc) = val;
270  v = make_value(is_value_constant, nc);
271  }
272  else
275  }
276  else
279  return v;
280 }
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
bool scalar_integer_type_p(type)
Definition: type.c:3276
bool float_type_p(type)
Definition: type.c:3263
#define type_functional_p(x)
Definition: ri.h:2950
#define functional_result(x)
Definition: ri.h:1444
#define type_functional(x)
Definition: ri.h:2952
@ is_constant_litteral
Definition: ri.h:820
@ is_constant_float
Definition: ri.h:818
#define constant_call_p(x)
Definition: ri.h:860
#define entity_type(x)
Definition: ri.h:2792
#define constant_call(x)
Definition: ri.h:862

References constant_call, constant_call_p, constant_float, constant_float_p, constant_int, constant_int_p, entity_local_name(), entity_type, f(), float_type_p(), functional_result, is_constant_float, is_constant_int, is_constant_litteral, is_value_constant, make_constant(), make_value(), NIL, scalar_integer_type_p(), type_functional, type_functional_p, and value_undefined.

Referenced by EvalCall().

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

◆ EvalExpression()

value EvalExpression ( expression  e)

Evaluate statically an expression.

cproto-generated files

If the expression can be evaluated regardless of the store and regardless of the target machine, and if the expression type is integer or float, return a constant value. Else, return a value unknown.

To accept dependencies on target architecture, set the property "EVAL_SIZEOF" to true.

A new value is always allocated.

If you are not interested in the object value, but simply to the integer value of a constant expression, see expression_integer_value().

This function is not fully implemented. It does not take care of logical (apparently) and string expressions. Some intrinsic operators are not evaluated. Floating point expressions are not as well covered as integer expression.

It is not clear if the evaluation of floating point expressions should be considered target dependent (e.g. for GPU code) or if the IEEE floating point standard is considered strongly enforced.

If information about the store used to evaluate the expression, i.e. preconditions, use precondition_minmax_of_expression()

The algorithm is built on a recursive analysis of the expression structure. Lower level functions are called until basic atoms are reached. The success of basic atom evaluation depend on the atom type:

reference: right now, the evaluation fails because we do not compute predicates on variables, unless the variable type is qualified by const.

call: a call to a user function is not evaluated. a call to an intrinsic function is successfully evaluated if arguments can be evaluated. a call to a constant function is evaluated if its basic type is integer.

range: a range is not evaluated.

Definition at line 108 of file eval.c.

109 {
110  return EvalSyntax(expression_syntax(e));
111 }
value EvalSyntax(syntax s)
Definition: eval.c:113
#define expression_syntax(x)
Definition: ri.h:1247

References EvalSyntax(), and expression_syntax.

Referenced by cell_is_xxx_p(), EvalBinaryOp(), EvalConditionalOp(), EvalNaryOp(), EvalSyntax(), EvalUnaryOp(), expression_integer_value(), ExpressionToInt(), extended_integer_constant_expression_p(), extended_integer_constant_expression_p_to_int(), InitializeEnumMemberValues(), MakeDataValueSet(), MakeValueSymbolic(), offset_array_reference(), offset_points_to_cell(), reference_to_points_to_translations(), reference_to_type(), simplified_reference(), subscript_expressions_to_constant_subscript_expressions(), xml_Argument(), xml_AssignArgument(), xml_expression(), and xml_Transposition().

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

◆ EvalIntrinsic()

value EvalIntrinsic ( entity  e,
list  la 
)

This function tries to evaluate a call to an intrinsic function.

right now, we only try to evaluate unary and binary intrinsic functions, ie. Fortran operators.

e is the intrinsic function.

la is the list of arguments.

Parameters
laa

Definition at line 290 of file eval.c.

291 {
292  value v;
293  int token;
294 
295  if ((token = IsUnaryOperator(e)) > 0)
296  v = EvalUnaryOp(token, la);
297  else if ((token = IsBinaryOperator(e)) > 0)
298  v = EvalBinaryOp(token, la);
299  else if ((token = IsNaryOperator(e)) > 0)
300  v = EvalNaryOp(token, la);
301  else if (ENTITY_CONDITIONAL_P(e))
302  v = EvalConditionalOp(la);
303  else
305 
306  return(v);
307 }
#define ENTITY_CONDITIONAL_P(e)
int IsUnaryOperator(entity e)
Definition: eval.c:632
value EvalNaryOp(int t, list la)
Definition: eval.c:591
value EvalBinaryOp(int t, list la)
t defines the operator and la is a list to two sub-expressions.
Definition: eval.c:385
value EvalConditionalOp(list la)
Definition: eval.c:309
int IsNaryOperator(entity e)
Definition: eval.c:746
value EvalUnaryOp(int t, list la)
Definition: eval.c:349
int IsBinaryOperator(entity e)
FI: These string constants are defined in ri-util.h and the tokens in ri-util/operator....
Definition: eval.c:660

References ENTITY_CONDITIONAL_P, EvalBinaryOp(), EvalConditionalOp(), EvalNaryOp(), EvalUnaryOp(), is_value_unknown, IsBinaryOperator(), IsNaryOperator(), IsUnaryOperator(), make_value(), and NIL.

Referenced by EvalCall().

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

◆ EvalNaryOp()

value EvalNaryOp ( int  t,
list  la 
)

2 operands at least are needed

Parameters
laa

Definition at line 591 of file eval.c.

592 {
595  int new_arg = 0;
596  bool first_arg_p = true;
597 
598  /* 2 operands at least are needed */
599  assert(la != NIL && CDR(la) != NIL);
600 
601  MAP(EXPRESSION, e, {
602  v = EvalExpression(e);
604  new_arg = constant_int(value_constant(v));
605  if (first_arg_p) {
606  first_arg_p = false;
607  w = v;
608  }
609  else {
610  switch(t) {
611  case MAXIMUM:
613  new_arg);
614  break;
615  case MINIMUM:
617  new_arg);
618  break;
619  default:
620  return v;
621  }
622  free_value(v);
623  }
624  }
625  else
626  return(v);
627  }, la);
628 
629  return(w);
630 }
#define MIN(x, y)
minimum and maximum if they are defined somewhere else, they are very likely to be defined the same w...
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
#define assert(ex)
Definition: newgen_assert.h:41
#define MAXIMUM
Definition: operator.h:50
#define MINIMUM
Definition: operator.h:49
#define MAX(x, y)
Definition: string.c:110

References assert, CDR, constant_int, constant_int_p, EvalExpression(), EXPRESSION, free_value(), MAP, MAX, MAXIMUM, MIN, MINIMUM, NIL, value_constant, value_constant_p, and value_undefined.

Referenced by EvalIntrinsic().

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

◆ EvalSizeofexpression()

value EvalSizeofexpression ( sizeofexpression  soe)
Parameters
soeoe

Definition at line 210 of file eval.c.

211 {
212  type t = type_undefined;
214  _int i;
215 
218 
219  t = expression_to_type(e);
220  }
221  else {
222  t = sizeofexpression_type(soe);
223  }
224 
225  i = type_memory_size(t);
227 
229  free_type(t);
230 
231  return v;
232 }
value make_value_constant(constant _field_)
Definition: ri.c:2841
constant make_constant_int(intptr_t _field_)
Definition: ri.c:409
void free_type(type p)
Definition: ri.c:2658
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
int type_memory_size(type)
Definition: size.c:248
#define sizeofexpression_type(x)
Definition: ri.h:2406
#define sizeofexpression_expression(x)
Definition: ri.h:2409
#define sizeofexpression_expression_p(x)
Definition: ri.h:2407
#define type_undefined
Definition: ri.h:2883

References expression_to_type(), free_type(), make_constant_int(), make_value_constant(), sizeofexpression_expression, sizeofexpression_expression_p, sizeofexpression_type, type_memory_size(), type_undefined, and value_undefined.

Referenced by EvalSyntax(), expression_constant(), expression_to_int(), and integer_expression_to_transformer().

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

◆ EvalSyntax()

value EvalSyntax ( syntax  s)

Is it a reference to a const variable?

SG: sizeof is architecture dependant, it is better not to evaluate it by default

Definition at line 113 of file eval.c.

114 {
116 
117  switch (syntax_tag(s)) {
118  case is_syntax_reference: {
119  /* Is it a reference to a const variable? */
121  entity var = reference_variable(r);
122  if(const_variable_p(var)) {
123  value i = entity_initial(var);
124  if(value_constant_p(i))
125  v = copy_value(entity_initial(var));
126  else if(value_expression_p(i)) {
128  v = EvalExpression(ie);
129  }
130  else
131  v = make_value_unknown();
132  }
133  else
134  v = make_value_unknown();
135  break;
136  }
137  case is_syntax_range:
138  v = make_value_unknown();
139  break;
140  case is_syntax_call:
141  v = EvalCall((syntax_call(s)));
142  break;
143  case is_syntax_cast:
144  v = make_value_unknown();
145  break;
147  /* SG: sizeof is architecture dependant, it is better not to
148  evaluate it by default */
149  if(get_bool_property("EVAL_SIZEOF"))
151  else
152  v = make_value_unknown();
153  break;
154  case is_syntax_subscript:
156  case is_syntax_va_arg:
157  v = make_value_unknown();
158  break;
159  default:
160  pips_internal_error("Unexpected syntax tag %d\n", syntax_tag(s));
161  abort();
162  }
163 
164  return v;
165 }
value copy_value(value p)
VALUE.
Definition: ri.c:2784
#define abort()
Definition: misc-local.h:53
value EvalCall(call c)
only calls to constant, symbolic or intrinsic functions might be evaluated.
Definition: eval.c:170
value EvalSizeofexpression(sizeofexpression soe)
Definition: eval.c:210
bool const_variable_p(entity)
Definition: variable.c:1687
#define syntax_reference(x)
Definition: ri.h:2730
#define syntax_tag(x)
Definition: ri.h:2727
@ 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 syntax_sizeofexpression(x)
Definition: ri.h:2742
#define syntax_call(x)
Definition: ri.h:2736
#define value_expression_p(x)
Definition: ri.h:3080
#define value_expression(x)
Definition: ri.h:3082

References abort, const_variable_p(), copy_value(), entity_initial, EvalCall(), EvalExpression(), EvalSizeofexpression(), get_bool_property(), 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, make_value_unknown(), pips_internal_error, reference_variable, syntax_call, syntax_reference, syntax_sizeofexpression, syntax_tag, value_constant_p, value_expression, value_expression_p, and value_undefined.

Referenced by EvalExpression().

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

◆ EvalUnaryOp()

value EvalUnaryOp ( int  t,
list  la 
)
Parameters
laa

Definition at line 349 of file eval.c.

350 {
351  value vout, v;
352  int arg;
353 
354  assert(la != NIL);
355  v = EvalExpression(EXPRESSION(CAR(la)));
357  arg = constant_int(value_constant(v));
358  else
359  return(v);
360 
361  if (t == MINUS) {
362  constant_int(value_constant(v)) = -arg;
363  vout = v;
364  }
365  else if (t == PLUS) {
366  constant_int(value_constant(v)) = arg;
367  vout = v;
368  }
369  else if (t == NOT) {
370  constant_int(value_constant(v)) = arg!=0;
371  vout = v;
372  }
373  else {
374  free_value(v);
376  }
377 
378  return(vout);
379 }
#define NOT
Definition: operator.h:40

References assert, CAR, constant_int, constant_int_p, EvalExpression(), EXPRESSION, free_value(), is_value_unknown, make_value(), MINUS, NIL, NOT, PLUS, value_constant, and value_constant_p.

Referenced by EvalIntrinsic().

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

◆ expression_integer_value()

bool expression_integer_value ( expression  e,
intptr_t pval 
)
Parameters
pvalval

Definition at line 792 of file eval.c.

793 {
794  bool is_int = false;
795  value v = EvalExpression(e);
796 
798  *pval = constant_int(value_constant(v));
799  is_int = true;
800  }
801 
802  free_value(v);
803  return is_int;
804 }
#define is_int
Definition: run-time.c:574

References constant_int, constant_int_p, EvalExpression(), free_value(), is_int, value_constant, and value_constant_p.

Referenced by array_references_may_conflict_p(), c_dim_string(), c_reference(), cell_reference_compare(), comparable_statements_on_distance_p(), compare_statements_on_distance_to_origin(), conflict_is_a_real_conflict_p(), consecutive_expression_p(), constant_image_p(), constant_reference_to_normalized_constant_reference(), convert_bound_expression(), copy_image_p(), dag_normalize(), declarations_to_dimensions(), dimension_size(), do_group_statement_constant(), do_isolate_statement_preconditions_satisified_p(), do_loop_unroll(), do_loop_unroll_with_prologue(), do_simdizer_init(), do_solve_hardware_constraints_on_volume(), expression_negative_integer_value_p(), fcs_call_flt(), freia_convolution_width_height(), freia_extract_kernel(), full_loop_unroll(), HpfcExpressionToInt(), loop_fully_unrollable_p(), loop_nest_to_offset(), make_condition_from_loop(), make_op_exp(), make_send_receive_conversion(), make_transStat(), MakeCaseStatement(), MakeDimension(), negative_expression_p(), normalize_integer_constant_expression(), NumberOfElements(), old_effects_conflict_p(), points_to_cell_update_last_subscript(), positive_expression_p(), range_count(), region_to_minimal_dimensions(), simd_loop_unroll(), size_of_dimension(), SizeOfIthDimension(), st_dimension_bound_as_string(), st_dimension_reference_as_string(), st_loop(), subscripted_field_list_to_type(), symbolic_tiling_valid_p(), terapix_loop_optimizer(), terapixify_loops(), update_range(), ValueSizeOfDimension(), variable_references_may_conflict_p(), variable_to_string(), words_dimension(), xml_Argument(), xml_AssignArgument(), xml_Bounds(), xml_Bounds_and_Stride(), xml_declarations(), and xml_dim_string().

+ Here is the call graph for this function:

◆ expression_linear_p()

bool expression_linear_p ( expression  e)

returns if e is already normalized and linear.

FI: should be moved into expression.c. Treacherous because the normalization is assumed to have occured earlier.

Definition at line 951 of file eval.c.

952 {
955 }
#define normalized_linear_p(x)
Definition: ri.h:1779
#define expression_normalized(x)
Definition: ri.h:1249
#define normalized_undefined_p(x)
Definition: ri.h:1746

References expression_normalized, normalized_linear_p, and normalized_undefined_p.

Referenced by convert_bound_expression(), expression_flt(), reference_filter(), and substitute_and_create().

+ Here is the caller graph for this function:

◆ expression_negative_integer_value_p()

bool expression_negative_integer_value_p ( expression  e)

Return true iff the expression has an integer value known statically and this value is negative.

All leaves of the expression tree must be constant integer.

If preconditions are available, a more general expression can be evaluated using precondition_minmax_of_expression().

Definition at line 814 of file eval.c.

814  {
815  intptr_t v;
816  return expression_integer_value(e, &v) && (v < 0);
817 }

References expression_integer_value(), and intptr_t.

+ Here is the call graph for this function:

◆ ipow()

int ipow ( int  vg,
int  vd 
)

FI: such a function should exist in Linear/arithmetique.

FI: should it return a long long int?

Parameters
vgg
vdd

Definition at line 769 of file eval.c.

770 {
771  int i = 1;
772 
773  assert(vd >= 0);
774 
775  while (vd-- > 0)
776  i *= vg;
777 
778  return(i);
779 }

References assert.

Referenced by binary_to_normalized(), EvalBinaryOp(), and partial_eval_power_operator().

+ Here is the caller graph for this function:

◆ IsBinaryOperator()

int IsBinaryOperator ( entity  e)

FI: These string constants are defined in ri-util.h and the tokens in ri-util/operator.h.

Definition at line 660 of file eval.c.

661 {
662  int token;
663  const char* n = entity_local_name(e);
664 
667  token = MINUS;
668  else if (same_string_p(n, PLUS_OPERATOR_NAME)
670  token = PLUS;
672  token = STAR;
673  else if (same_string_p(n, DIVIDE_OPERATOR_NAME))
674  token = SLASH;
675  else if (same_string_p(n, POWER_OPERATOR_NAME))
676  token = POWER;
679  token = MOD;
682  token = EQ;
685  token = NE;
688  token = EQV;
689  else if (same_string_p(n, EQUIV_OPERATOR_NAME))
690  token = NEQV;
693  token = GT;
696  token = LT;
699  token = GE;
702  token = LE;
703  else if (same_string_p(n, OR_OPERATOR_NAME)
705  token = OR;
706  else if (same_string_p(n, AND_OPERATOR_NAME)
708  token = AND;
710  token = BITWISE_AND;
712  token = BITWISE_OR;
714  token = BITWISE_XOR;
716  token = LEFT_SHIFT;
718  token = RIGHT_SHIFT;
719 
720  else if (same_string_p(n, ASSIGN_OPERATOR_NAME)) // C operators
721  token = ASSIGN;
723  token = MULTIPLY_UPDATE;
725  token = DIVIDE_UPDATE;
727  token = PLUS_UPDATE;
729  token = MINUS_UPDATE;
731  token = LEFT_SHIFT_UPDATE;
733  token = RIGHT_SHIFT_UPDATE;
735  token = BITWISE_OR_UPDATE;
736 
739  token = CAST_OP;
740  else
741  token = -1;
742 
743  return(token);
744 }
#define same_string_p(s1, s2)
#define LEFT_SHIFT_UPDATE
Definition: operator.h:67
#define CAST_OP
Definition: operator.h:51
#define ASSIGN
Definition: operator.h:58
#define RIGHT_SHIFT_UPDATE
Definition: operator.h:68
#define BITWISE_OR_UPDATE
Definition: operator.h:69
#define PLUS_UPDATE
Definition: operator.h:65
#define MINUS_UPDATE
Definition: operator.h:66
#define LE
Definition: operator.h:36
#define MULTIPLY_UPDATE
Definition: operator.h:63
#define DIVIDE_UPDATE
Definition: operator.h:64
#define BITWISE_OR_OPERATOR_NAME
#define POWER_OPERATOR_NAME
#define BITWISE_XOR_OPERATOR_NAME
#define C_LESS_OR_EQUAL_OPERATOR_NAME
#define C_AND_OPERATOR_NAME
#define GREATER_THAN_OPERATOR_NAME
#define C_GREATER_OR_EQUAL_OPERATOR_NAME
#define BITWISE_OR_UPDATE_OPERATOR_NAME
#define C_MODULO_OPERATOR_NAME
#define MINUS_OPERATOR_NAME
#define LESS_THAN_OPERATOR_NAME
#define EQUIV_OPERATOR_NAME
#define DIVIDE_UPDATE_OPERATOR_NAME
#define PLUS_OPERATOR_NAME
#define EQUAL_OPERATOR_NAME
#define C_NON_EQUAL_OPERATOR_NAME
#define LEFT_SHIFT_UPDATE_OPERATOR_NAME
#define MULTIPLY_UPDATE_OPERATOR_NAME
#define LEFT_SHIFT_OPERATOR_NAME
#define AND_OPERATOR_NAME
FI: intrinsics are defined at a third place after bootstrap and effects! I guess the name should be d...
#define MINUS_UPDATE_OPERATOR_NAME
#define IMPLIED_DCOMPLEX_NAME
Definition: ri-util-local.h:89
#define DIVIDE_OPERATOR_NAME
#define RIGHT_SHIFT_UPDATE_OPERATOR_NAME
#define C_LESS_THAN_OPERATOR_NAME
#define GREATER_OR_EQUAL_OPERATOR_NAME
#define PLUS_UPDATE_OPERATOR_NAME
#define MINUS_C_OPERATOR_NAME
#define MULTIPLY_OPERATOR_NAME
#define LESS_OR_EQUAL_OPERATOR_NAME
#define C_OR_OPERATOR_NAME
#define BITWISE_AND_OPERATOR_NAME
#define RIGHT_SHIFT_OPERATOR_NAME
#define IMPLIED_COMPLEX_NAME
Definition: ri-util-local.h:88
#define OR_OPERATOR_NAME
#define NON_EQUAL_OPERATOR_NAME
#define C_EQUAL_OPERATOR_NAME
#define ASSIGN_OPERATOR_NAME
Definition: ri-util-local.h:95
#define MODULO_OPERATOR_NAME
#define PLUS_C_OPERATOR_NAME

References AND, AND_OPERATOR_NAME, ASSIGN, ASSIGN_OPERATOR_NAME, BITWISE_AND, BITWISE_AND_OPERATOR_NAME, BITWISE_OR, BITWISE_OR_OPERATOR_NAME, BITWISE_OR_UPDATE, BITWISE_OR_UPDATE_OPERATOR_NAME, BITWISE_XOR, BITWISE_XOR_OPERATOR_NAME, C_AND_OPERATOR_NAME, C_EQUAL_OPERATOR_NAME, C_GREATER_OR_EQUAL_OPERATOR_NAME, C_LESS_OR_EQUAL_OPERATOR_NAME, C_LESS_THAN_OPERATOR_NAME, C_MODULO_OPERATOR_NAME, C_NON_EQUAL_OPERATOR_NAME, C_OR_OPERATOR_NAME, CAST_OP, DIVIDE_OPERATOR_NAME, DIVIDE_UPDATE, DIVIDE_UPDATE_OPERATOR_NAME, entity_local_name(), EQ, EQUAL_OPERATOR_NAME, EQUIV_OPERATOR_NAME, EQV, GE, GREATER_OR_EQUAL_OPERATOR_NAME, GREATER_THAN_OPERATOR_NAME, GT, IMPLIED_COMPLEX_NAME, IMPLIED_DCOMPLEX_NAME, LE, LEFT_SHIFT, LEFT_SHIFT_OPERATOR_NAME, LEFT_SHIFT_UPDATE, LEFT_SHIFT_UPDATE_OPERATOR_NAME, LESS_OR_EQUAL_OPERATOR_NAME, LESS_THAN_OPERATOR_NAME, LT, MINUS, MINUS_C_OPERATOR_NAME, MINUS_OPERATOR_NAME, MINUS_UPDATE, MINUS_UPDATE_OPERATOR_NAME, MOD, MODULO_OPERATOR_NAME, MULTIPLY_OPERATOR_NAME, MULTIPLY_UPDATE, MULTIPLY_UPDATE_OPERATOR_NAME, NE, NEQV, NON_EQUAL_OPERATOR_NAME, OR, OR_OPERATOR_NAME, PLUS, PLUS_C_OPERATOR_NAME, PLUS_OPERATOR_NAME, PLUS_UPDATE, PLUS_UPDATE_OPERATOR_NAME, POWER, POWER_OPERATOR_NAME, RIGHT_SHIFT, RIGHT_SHIFT_OPERATOR_NAME, RIGHT_SHIFT_UPDATE, RIGHT_SHIFT_UPDATE_OPERATOR_NAME, same_string_p, SLASH, and STAR.

Referenced by EvalIntrinsic().

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

◆ IsNaryOperator()

int IsNaryOperator ( entity  e)

Definition at line 746 of file eval.c.

747 {
748  int token;
749 
750  if (strcmp(entity_local_name(e), MIN0_OPERATOR_NAME) == 0)
751  token = MINIMUM;
752  else if (strcmp(entity_local_name(e), MAX0_OPERATOR_NAME) == 0)
753  token = MAXIMUM;
754  else if (strcmp(entity_local_name(e), MIN_OPERATOR_NAME) == 0)
755  token = MINIMUM;
756  else if (strcmp(entity_local_name(e), MAX_OPERATOR_NAME) == 0)
757  token = MAXIMUM;
758  else
759  token = -1;
760 
761  return token;
762 }
#define MAX_OPERATOR_NAME
#define MAX0_OPERATOR_NAME
#define MIN0_OPERATOR_NAME
#define MIN_OPERATOR_NAME

References entity_local_name(), MAX0_OPERATOR_NAME, MAX_OPERATOR_NAME, MAXIMUM, MIN0_OPERATOR_NAME, MIN_OPERATOR_NAME, and MINIMUM.

Referenced by EvalIntrinsic().

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

◆ IsUnaryOperator()

int IsUnaryOperator ( entity  e)

Definition at line 632 of file eval.c.

633 {
634  int token;
635  const char* n = entity_local_name(e);
636 
638  token = MINUS;
640  token = PLUS;
641  else if (same_string_p(n, NOT_OPERATOR_NAME)
643  token = NOT;
645  token = POST_INCREMENT;
647  token = POST_DECREMENT;
649  token = PRE_INCREMENT;
651  token = PRE_DECREMENT;
652  else
653  token = -1;
654 
655  return(token);
656 }
#define POST_DECREMENT
Definition: operator.h:60
#define PRE_INCREMENT
Definition: operator.h:61
#define POST_INCREMENT
Definition: operator.h:59
#define PRE_DECREMENT
Definition: operator.h:62
#define POST_DECREMENT_OPERATOR_NAME
Definition: ri-util-local.h:98
#define C_NOT_OPERATOR_NAME
#define PRE_DECREMENT_OPERATOR_NAME
#define UNARY_MINUS_OPERATOR_NAME
#define UNARY_PLUS_OPERATOR_NAME
#define PRE_INCREMENT_OPERATOR_NAME
Definition: ri-util-local.h:99
#define POST_INCREMENT_OPERATOR_NAME
Definition: ri-util-local.h:97
#define NOT_OPERATOR_NAME

References C_NOT_OPERATOR_NAME, entity_local_name(), MINUS, NOT, NOT_OPERATOR_NAME, PLUS, POST_DECREMENT, POST_DECREMENT_OPERATOR_NAME, POST_INCREMENT, POST_INCREMENT_OPERATOR_NAME, PRE_DECREMENT, PRE_DECREMENT_OPERATOR_NAME, PRE_INCREMENT, PRE_INCREMENT_OPERATOR_NAME, same_string_p, UNARY_MINUS_OPERATOR_NAME, and UNARY_PLUS_OPERATOR_NAME.

Referenced by EvalIntrinsic().

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

◆ negative_expression_p()

bool negative_expression_p ( expression  e)

Use constants and type information to decide if the value of sigma(e) is always negative, e.g.

<=0. If this can be proven, true is returned.

false is returned when no decision can be made, i.e. negative_expression_p(e)==false does not imply positive_expression_p(e)

Similar and linked to previous function

We assume an operator is used

We can check a few cases recursively...

Definition at line 896 of file eval.c.

897 {
898  bool negative_p = false; // In general, false because no conclusion can be reached
899  intptr_t v;
900  if(expression_integer_value(e, &v)) {
901  negative_p = v<=0;
902  }
903  else {
904  syntax s = expression_syntax(e);
905 
906  if(syntax_call_p(s)) {
907  call c = syntax_call(s);
908  entity f = call_function(c);
909  type t = entity_type(f);
910  pips_assert("t is a functional type", type_functional_p(t));
912  if(overloaded_type_p(rt)) { /* We assume an operator is used */
913  /* We can check a few cases recursively... */
914  list args = call_arguments(c);
915  intptr_t l = gen_length(args);
916  if(l==1) {
917  expression arg = EXPRESSION(CAR(args));
918  if(ENTITY_UNARY_MINUS_P(f)) {
919  negative_p = positive_expression_p(arg); // Maybe zero, but no chance for sigma(x)>0
920  }
921  }
922  else if(l==2) {
923  expression arg1 = EXPRESSION(CAR(args));
924  expression arg2 = EXPRESSION(CAR(CDR(args)));
925  if(ENTITY_MINUS_P(f)) {
926  negative_p = negative_expression_p(arg1) && positive_expression_p(arg2);
927  }
928  else if(ENTITY_PLUS_P(f)) {
929  negative_p = negative_expression_p(arg1) && negative_expression_p(arg2);
930  }
931  else if(ENTITY_MULTIPLY_P(f)) {
932  negative_p = (negative_expression_p(arg1) && positive_expression_p(arg2))
933  || (positive_expression_p(arg1) && negative_expression_p(arg2));
934  }
935  else if(ENTITY_DIVIDE_P(f)) {
936  negative_p = (negative_expression_p(arg1) && positive_expression_p(arg2))
937  || (positive_expression_p(arg1) && negative_expression_p(arg2));
938  }
939  }
940  }
941  }
942  }
943  return negative_p;
944 }
#define ENTITY_DIVIDE_P(e)
#define ENTITY_MINUS_P(e)
#define ENTITY_UNARY_MINUS_P(e)
#define ENTITY_PLUS_P(e)
#define ENTITY_MULTIPLY_P(e)
bool positive_expression_p(expression e)
Use constants and type information to decide if the value of sigma(e) is always positive,...
Definition: eval.c:826
bool negative_expression_p(expression e)
Use constants and type information to decide if the value of sigma(e) is always negative,...
Definition: eval.c:896
bool overloaded_type_p(type)
Returns true if t is a variable type with a basic overloaded.
Definition: type.c:2666
#define syntax_call_p(x)
Definition: ri.h:2734

References call_arguments, call_function, CAR, CDR, ENTITY_DIVIDE_P, ENTITY_MINUS_P, ENTITY_MULTIPLY_P, ENTITY_PLUS_P, entity_type, ENTITY_UNARY_MINUS_P, EXPRESSION, expression_integer_value(), expression_syntax, f(), functional_result, gen_length(), intptr_t, overloaded_type_p(), pips_assert, positive_expression_p(), syntax_call, syntax_call_p, type_functional, and type_functional_p.

Referenced by add_index_range_conditions(), C_loop_range(), incrementation_expression_to_increment(), and positive_expression_p().

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

◆ normalize_integer_constant_expression()

expression normalize_integer_constant_expression ( expression  e)

Allocate a new expression equivalent to e, but constant expressions are evaluated.

This function is used to normalize array dimensions to obtain type equality for a[2] and a[4/2].

Definition at line 1112 of file eval.c.

1113 {
1115  intptr_t i;
1116  if(expression_integer_value(e, &i)) {
1117  ne = int_to_expression((int) i);
1118  }
1119  else
1120  ne = copy_expression(e);
1121  return ne;
1122 }

References copy_expression(), expression_integer_value(), expression_undefined, int_to_expression(), and intptr_t.

Referenced by dimensions_to_normalized_dimensions().

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

◆ positive_expression_p()

bool positive_expression_p ( expression  e)

Use constants and type information to decide if the value of sigma(e) is always positive, e.g.

>=0

See negative_expression_p()

Should we define positive_integer_expression_p() and check the expression type?

We assume an operator is used

We can check a few cases recursively...

Definition at line 826 of file eval.c.

827 {
828  bool positive_p = false; // In general, false because no conclusion can be reached
829  intptr_t v;
830  if(expression_integer_value(e, &v)) {
831  positive_p = v>=0;
832  }
833  else {
834  syntax s = expression_syntax(e);
835 
836  if(syntax_reference_p(s)) {
839  positive_p = unsigned_type_p(t);
840  }
841  else if(syntax_call_p(s)) {
842  call c = syntax_call(s);
843  entity f = call_function(c);
844  type t = entity_type(f);
845  pips_assert("t is a functional type", type_functional_p(t));
847  if(unsigned_type_p(rt))
848  positive_p = true;
849  else if(overloaded_type_p(rt)) { /* We assume an operator is used */
850  /* We can check a few cases recursively... */
851  list args = call_arguments(c);
852  intptr_t l = gen_length(args);
853  if(l==1) {
854  expression arg = EXPRESSION(CAR(args));
855  if(ENTITY_UNARY_MINUS_P(f)) {
856  positive_p = negative_expression_p(arg); // Maybe zero, but no chance for sigma(x)>0
857  }
858  else if(ENTITY_IABS_P(f) || ENTITY_ABS_P(f) || ENTITY_DABS_P(f)
859  || ENTITY_CABS_P(f)) {
860  positive_p = true;
861  }
862  }
863  else if(l==2) {
864  expression arg1 = EXPRESSION(CAR(args));
865  expression arg2 = EXPRESSION(CAR(CDR(args)));
866  if(ENTITY_MINUS_P(f)) {
867  positive_p = positive_expression_p(arg1) && negative_expression_p(arg2);
868  }
869  else if(ENTITY_PLUS_P(f)) {
870  positive_p = positive_expression_p(arg1) && positive_expression_p(arg2);
871  }
872  else if(ENTITY_MULTIPLY_P(f)) {
873  positive_p = (positive_expression_p(arg1) && positive_expression_p(arg2))
874  || (negative_expression_p(arg1) && negative_expression_p(arg2));
875  }
876  else if(ENTITY_DIVIDE_P(f)) {
877  positive_p = (positive_expression_p(arg1) && positive_expression_p(arg2))
878  || (negative_expression_p(arg1) && negative_expression_p(arg2));
879  }
880  }
881  }
882  }
883  }
884  return positive_p;
885 }
#define ENTITY_DABS_P(e)
#define ENTITY_CABS_P(e)
#define ENTITY_IABS_P(e)
#define ENTITY_ABS_P(e)
type ultimate_type(type)
Definition: type.c:3466
bool unsigned_type_p(type)
Predicates on types.
Definition: type.c:2821
#define syntax_reference_p(x)
Definition: ri.h:2728

References call_arguments, call_function, CAR, CDR, ENTITY_ABS_P, ENTITY_CABS_P, ENTITY_DABS_P, ENTITY_DIVIDE_P, ENTITY_IABS_P, ENTITY_MINUS_P, ENTITY_MULTIPLY_P, ENTITY_PLUS_P, entity_type, ENTITY_UNARY_MINUS_P, EXPRESSION, expression_integer_value(), expression_syntax, f(), functional_result, gen_length(), intptr_t, negative_expression_p(), overloaded_type_p(), pips_assert, reference_variable, syntax_call, syntax_call_p, syntax_reference, syntax_reference_p, type_functional, type_functional_p, ultimate_type(), and unsigned_type_p().

Referenced by add_index_range_conditions(), C_loop_range(), incrementation_expression_to_increment(), and negative_expression_p().

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

◆ range_count()

bool range_count ( range  r,
intptr_t pcount 
)

The range count only can be evaluated if the three range expressions are constant and if the increment is non zero.

On failure, a zero count is returned. See also SizeOfRange().

inc>0

Parameters
pcountcount

Definition at line 979 of file eval.c.

980 {
981  bool success = false;
982  intptr_t l, u, inc;
983 
987  && inc != 0 ) {
988 
989  if(inc<0) {
990  * pcount = ((l-u)/(-inc))+1;
991  }
992  else /* inc>0 */ {
993  * pcount = ((u-l)/inc)+1;
994  }
995 
996  if(* pcount < 0)
997  *pcount = 0;
998 
999  success = true;
1000  }
1001  else {
1002  * pcount = 0;
1003  success = false;
1004  }
1005 
1006  return success;
1007 }
bool success
Definition: gpips-local.h:59
#define range_upper(x)
Definition: ri.h:2290
#define range_increment(x)
Definition: ri.h:2292
#define range_lower(x)
Definition: ri.h:2288

References expression_integer_value(), intptr_t, range_increment, range_lower, and range_upper.

Referenced by implied_do_reference_number().

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

◆ range_to_expression()

expression range_to_expression ( range  r,
enum range_to_expression_mode  mode 
)

computes the distance between the lower bound and the upper bound of the range

Parameters
rrange to analyse
modewether we compute the distance or count the number of iterations
Returns
appropriate distance or count

Definition at line 963 of file eval.c.

964 {
971  return distance;
972 }
#define range_to_nbiter_p(e)
expression make_op_exp(char *op_name, expression exp1, expression exp2)
================================================================
Definition: expression.c:2012

References copy_expression(), DIVIDE_OPERATOR_NAME, int_to_expression(), make_op_exp(), MINUS_OPERATOR_NAME, PLUS_OPERATOR_NAME, range_increment, range_lower, range_to_nbiter_p, and range_upper.

Referenced by add_loop_parallel_threshold(), build_iteration_list(), do_loop_expansion(), do_loop_expansion_init(), sesamify(), simd_loop_unroll(), simdizer_auto_tile(), and terapix_loop_handler().

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

◆ vect_const_p()

static bool vect_const_p ( Pvecteur  v)
static

returns true if v is not NULL and is constant

I make it "static" because it conflicts with a Linear library function. Both functions have the same name but a slightly different behavior. The Linear version returns 0 when a null vector is passed as argument. Francois Irigoin, 16 April 1990

See vect_constant_p() placed in linear/src/contrainte/predicats.c. Seems now OK.

Definition at line 1020 of file eval.c.

1021 {
1022  pips_assert("vect_const_p", v != NULL);
1023  return vect_size(v) == 1 && value_notzero_p(vect_coeff(TCST, v));
1024 }
#define value_notzero_p(val)
int vect_size(Pvecteur v)
package vecteur - reductions
Definition: reductions.c:47
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
Value vect_coeff(Variable var, Pvecteur vect)
Variable vect_coeff(Variable var, Pvecteur vect): coefficient de coordonnee var du vecteur vect —> So...
Definition: unaires.c:228

References pips_assert, TCST, value_notzero_p, vect_coeff(), and vect_size().

Referenced by vect_product().

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

◆ vect_product()

Pvecteur vect_product ( Pvecteur pv1,
Pvecteur pv2 
)

returns a Pvecteur equal to (*pv1) * (*pv2) if this product is linear or NULL otherwise.

the result is built from pv1 or pv2 and the other vector is removed.

Parameters
pv1v1
pv2v2

Definition at line 1032 of file eval.c.

1033 {
1034  Pvecteur vr;
1035 
1036  if (vect_const_p(*pv1)) {
1037  vr = vect_multiply(*pv2, vect_coeff(TCST, *pv1));
1038  vect_rm(*pv1);
1039  }
1040  else if (vect_const_p(*pv2)) {
1041  vr = vect_multiply(*pv1, vect_coeff(TCST, *pv2));
1042  vect_rm(*pv2);
1043  }
1044  else {
1045  vr = NULL;
1046  vect_rm(*pv1);
1047  vect_rm(*pv2);
1048  }
1049 
1050  *pv1 = NULL;
1051  *pv2 = NULL;
1052 
1053  return(vr);
1054 }
static bool vect_const_p(Pvecteur v)
returns true if v is not NULL and is constant
Definition: eval.c:1020
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
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78

References TCST, vect_coeff(), vect_const_p(), vect_multiply(), and vect_rm().

+ Here is the call graph for this function: