PIPS
eval.c
Go to the documentation of this file.
1 /*
2 
3  $Id: eval.c 23412 2017-08-09 15:07:09Z irigoin $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 
28 /*
29  * This file contains a set of functions to evaluate store independent
30  * expressions, especially integer expressions, which are key to loop
31  * parallelization.
32  *
33  * The key functions are:
34  *
35  * value EvalExpression(expression)
36  *
37  * bool expression_integer_value(expression, intptr_t *)
38  *
39  * bool expression_negative_integer_value_p(expression)
40  *
41  * bool positive_expression_p()
42  *
43  * bool negative_expression_p()
44  *
45  * expression range_to_expression()
46  *
47  * bool range_count()
48  *
49  * A few misplaced functions are here too: expression_linear_p(),
50  * ipow(), vect_const_p(), vect_product()
51  */
52 
53 #include <stdio.h>
54 #include <string.h>
55 #include <ctype.h>
56 
57 #include "linear.h"
58 
59 #include "genC.h"
60 #include "ri.h"
61 #include "misc.h"
62 
63 #include "ri-util.h"
64 #include "properties.h"
65 
66 #include "operator.h"
67 
68 /* Evaluate statically an expression. If the expression can be
69  * evaluated regardless of the store and regardless of the target
70  * machine, and if the expression type is integer or float, return a
71  * constant value. Else, return a value unknown.
72  *
73  * To accept dependencies on target architecture, set the property
74  * "EVAL_SIZEOF" to true.
75  *
76  * A new value is always allocated.
77  *
78  * If you are not interested in the object value, but simply to the
79  * integer value of a constant expression, see
80  * expression_integer_value().
81  *
82  * This function is not fully implemented. It does not take care of
83  * logical (apparently) and string expressions. Some intrinsic
84  * operators are not evaluated. Floating point expressions are not as
85  * well covered as integer expression.
86  *
87  * It is not clear if the evaluation of floating point expressions
88  * should be considered target dependent (e.g. for GPU code) or if the
89  * IEEE floating point standard is considered strongly enforced.
90  *
91  * If information about the store used to evaluate the expression,
92  * i.e. preconditions, use precondition_minmax_of_expression()
93  *
94  * The algorithm is built on a recursive analysis of the
95  * expression structure. Lower level functions are called until basic atoms
96  * are reached. The success of basic atom evaluation depend on the atom
97  * type:
98  *
99  * reference: right now, the evaluation fails because we do not compute
100  * predicates on variables, unless the variable type is qualified by const.
101  *
102  * call: a call to a user function is not evaluated. a call to an intrinsic
103  * function is successfully evaluated if arguments can be evaluated. a call
104  * to a constant function is evaluated if its basic type is integer.
105  *
106  * range: a range is not evaluated.
107  */
109 {
110  return EvalSyntax(expression_syntax(e));
111 }
112 
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 }
166 
167 /* only calls to constant, symbolic or intrinsic functions might be
168  * evaluated. recall that intrinsic functions are not known.
169  */
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 }
209 
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 }
233 
234 /* Constant c is returned as field of value v. */
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 }
281 
282 /* This function tries to evaluate a call to an intrinsic function.
283  * right now, we only try to evaluate unary and binary intrinsic
284  * functions, ie. Fortran operators.
285  *
286  * e is the intrinsic function.
287  *
288  * la is the list of arguments.
289  */
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 }
308 
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 }
347 
348 
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 }
380 
381 /* t defines the operator and la is a list to two sub-expressions.
382  *
383  * Integer and floatint point constants are evaluated.
384 */
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 }
590 
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 }
631 ␌
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 }
657 
658 /* FI: These string constants are defined in ri-util.h and the tokens
659  in ri-util/operator.h */
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 }
745 
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 }
763 ␌
764 /* FI: such a function should exist in Linear/arithmetique
765  *
766  * FI: should it return a long long int?
767  */
768 int
769 ipow(int vg, int vd)
770 {
771  int i = 1;
772 
773  assert(vd >= 0);
774 
775  while (vd-- > 0)
776  i *= vg;
777 
778  return(i);
779 }
780 
781 ␌
782 /*
783  * evaluates statically the value of an integer expression.
784  *
785  * returns true if an integer value could be computed and placed in pval.
786  *
787  * returns false otherwise.
788  *
789  * Based on EvalExpression()
790 */
791 bool
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 }
805 
806 
807 /* Return true iff the expression has an integer value known
808  * statically and this value is negative. All leaves of the expression
809  * tree must be constant integer.
810  *
811  * If preconditions are available, a more general expression can be
812  * evaluated using precondition_minmax_of_expression().
813  */
815  intptr_t v;
816  return expression_integer_value(e, &v) && (v < 0);
817 }
818 
819 /* Use constants and type information to decide if the value of
820  * sigma(e) is always positive, e.g. >=0
821  *
822  * See negative_expression_p()
823  *
824  * Should we define positive_integer_expression_p() and check the expression type?
825  */
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 }
886 
887 /* Use constants and type information to decide if the value of
888  * sigma(e) is always negative, e.g. <=0. If this can be proven, true is returned.
889  *
890  * false is returned when no decision can be made,
891  * i.e. negative_expression_p(e)==false does not imply
892  * positive_expression_p(e)
893  *
894  * Similar and linked to previous function
895  */
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 }
945 ␌
946 /* returns if e is already normalized and linear.
947  *
948  * FI: should be moved into expression.c. Treacherous because the
949  * normalization is assumed to have occured earlier.
950  */
952 {
955 }
956 ␌
957 /**
958  * computes the distance between the lower bound and the upper bound of the range
959  * @param r range to analyse
960  * @param mode wether we compute the distance or count the number of iterations
961  * @return appropriate distance or count
962  */
964 {
971  return distance;
972 }
973 
974 /* The range count only can be evaluated if the three range expressions
975  * are constant and if the increment is non zero. On failure, a zero
976  * count is returned. See also SizeOfRange().
977  */
978 bool
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 }
1008 
1009 ␌
1010 /* returns true if v is not NULL and is constant */
1011 /* I make it "static" because it conflicts with a Linear library function.
1012  * Both functions have the same name but a slightly different behavior.
1013  * The Linear version returns 0 when a null vector is passed as argument.
1014  * Francois Irigoin, 16 April 1990
1015  *
1016  * See vect_constant_p() placed in
1017  * linear/src/contrainte/predicats.c. Seems now OK.
1018  */
1019 static bool
1021 {
1022  pips_assert("vect_const_p", v != NULL);
1023  return vect_size(v) == 1 && value_notzero_p(vect_coeff(TCST, v));
1024 }
1025 
1026 /*
1027  returns a Pvecteur equal to (*pv1) * (*pv2) if this product is
1028  linear or NULL otherwise.
1029  the result is built from pv1 or pv2 and the other vector is removed.
1030 */
1031 Pvecteur
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 }
1055 ␌
1056 /* Allocate a new reference with evaluated subscripts
1057  *
1058  * For instance, return a[2] for a[10/2-3]
1059  *
1060  * This function deals with all kinds of references, including the
1061  * points-to references which use fields as subscripts.
1062  *
1063  * There is an ambiguity for a[*] where * may be considered a constant
1064  * in some passes of PIPS. However, it denotes a constant set of
1065  * references and not a constant reference. The returned reference is
1066  * undefined.
1067  */
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 }
1105 
1106 /* Allocate a new expression equivalent to e, but constant expressions
1107  * are evaluated.
1108  *
1109  * This function is used to normalize array dimensions to obtain type
1110  * equality for a[2] and a[4/2].
1111  */
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 }
constant make_constant(enum constant_utype tag, void *val)
Definition: ri.c:406
value make_value_unknown(void)
Definition: ri.c:2847
value make_value_constant(constant _field_)
Definition: ri.c:2841
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
value make_value(enum value_utype tag, void *val)
Definition: ri.c:2832
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
constant make_constant_int(intptr_t _field_)
Definition: ri.c:409
value copy_value(value p)
VALUE.
Definition: ri.c:2784
void free_type(type p)
Definition: ri.c:2658
void free_value(value p)
Definition: ri.c:2787
#define value_notzero_p(val)
#define MIN(x, y)
minimum and maximum if they are defined somewhere else, they are very likely to be defined the same w...
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
void gen_full_free_list(list l)
Definition: genClib.c:1023
#define OR
Definition: genspec.h:89
#define STAR
Definition: genspec.h:91
#define AND
Definition: genspec.h:88
bool success
Definition: gpips-local.h:59
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
size_t gen_length(const list l)
Definition: list.c:150
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#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 CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#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
int vect_size(Pvecteur v)
package vecteur - reductions
Definition: reductions.c:47
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_internal_error
Definition: misc-local.h:149
#define abort()
Definition: misc-local.h:53
#define pips_user_error
Definition: misc-local.h:147
#define assert(ex)
Definition: newgen_assert.h:41
#define same_string_p(s1, s2)
intptr_t _int
_INT
Definition: newgen_types.h:53
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
#define POWER
Definition: operator.h:46
#define POST_DECREMENT
Definition: operator.h:60
#define LEFT_SHIFT_UPDATE
Definition: operator.h:67
#define PRE_INCREMENT
Definition: operator.h:61
#define BITWISE_XOR
Definition: operator.h:54
#define LEFT_SHIFT
Definition: operator.h:56
#define CAST_OP
Definition: operator.h:51
#define GE
Definition: operator.h:34
#define RIGHT_SHIFT
Definition: operator.h:55
#define ASSIGN
Definition: operator.h:58
#define MINUS
Definition: operator.h:42
#define NE
Definition: operator.h:38
#define RIGHT_SHIFT_UPDATE
Definition: operator.h:68
#define MAXIMUM
Definition: operator.h:50
#define NEQV
Definition: operator.h:39
#define BITWISE_OR_UPDATE
Definition: operator.h:69
#define PLUS_UPDATE
Definition: operator.h:65
#define MINUS_UPDATE
Definition: operator.h:66
#define BITWISE_AND
Definition: operator.h:52
#define POST_INCREMENT
Definition: operator.h:59
#define LE
Definition: operator.h:36
#define PRE_DECREMENT
Definition: operator.h:62
#define LT
Definition: operator.h:37
#define BITWISE_OR
Definition: operator.h:53
#define MINIMUM
Definition: operator.h:49
#define GT
Definition: operator.h:35
#define EQ
Definition: operator.h:32
#define MULTIPLY_UPDATE
Definition: operator.h:63
#define DIVIDE_UPDATE
Definition: operator.h:64
#define MOD
Definition: operator.h:47
#define NOT
Definition: operator.h:40
#define EQV
Definition: operator.h:33
static bool constant_p(entity e)
This function return a bool indicating if related entity e represents a constant.
#define BITWISE_OR_OPERATOR_NAME
#define MAX_OPERATOR_NAME
#define POWER_OPERATOR_NAME
#define POST_DECREMENT_OPERATOR_NAME
Definition: ri-util-local.h:98
#define ENTITY_DIVIDE_P(e)
#define BITWISE_XOR_OPERATOR_NAME
#define C_LESS_OR_EQUAL_OPERATOR_NAME
#define ENTITY_DABS_P(e)
#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 ENTITY_MINUS_P(e)
#define LESS_THAN_OPERATOR_NAME
#define ENTITY_UNARY_MINUS_P(e)
#define EQUIV_OPERATOR_NAME
#define DIVIDE_UPDATE_OPERATOR_NAME
#define PLUS_OPERATOR_NAME
#define ENTITY_PLUS_P(e)
#define EQUAL_OPERATOR_NAME
#define ENTITY_MULTIPLY_P(e)
#define MAX0_OPERATOR_NAME
#define MIN0_OPERATOR_NAME
#define C_NON_EQUAL_OPERATOR_NAME
#define LEFT_SHIFT_UPDATE_OPERATOR_NAME
#define range_to_nbiter_p(e)
#define ENTITY_CONDITIONAL_P(e)
#define ENTITY_CABS_P(e)
#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 C_NOT_OPERATOR_NAME
#define ENTITY_IABS_P(e)
#define PRE_DECREMENT_OPERATOR_NAME
#define IMPLIED_DCOMPLEX_NAME
Definition: ri-util-local.h:89
#define DIVIDE_OPERATOR_NAME
#define UNARY_MINUS_OPERATOR_NAME
range_to_expression_mode
#define UNARY_PLUS_OPERATOR_NAME
#define RIGHT_SHIFT_UPDATE_OPERATOR_NAME
#define ENTITY_ABS_P(e)
#define C_LESS_THAN_OPERATOR_NAME
#define GREATER_OR_EQUAL_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 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 NOT_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
#define MIN_OPERATOR_NAME
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
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
Definition: eval.c:963
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
bool expression_linear_p(expression e)
returns if e is already normalized and linear.
Definition: eval.c:951
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
value EvalConditionalOp(list la)
Definition: eval.c:309
reference constant_reference_to_normalized_constant_reference(reference cr)
Allocate a new reference with evaluated subscripts.
Definition: eval.c:1068
Pvecteur vect_product(Pvecteur *pv1, Pvecteur *pv2)
returns a Pvecteur equal to (*pv1) * (*pv2) if this product is linear or NULL otherwise.
Definition: eval.c:1032
value EvalConstant(constant c)
Constant c is returned as field of value v.
Definition: eval.c:235
value EvalCall(call c)
only calls to constant, symbolic or intrinsic functions might be evaluated.
Definition: eval.c:170
value EvalExpression(expression e)
Evaluate statically an expression.
Definition: eval.c:108
value EvalSizeofexpression(sizeofexpression soe)
Definition: eval.c:210
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
int IsNaryOperator(entity e)
Definition: eval.c:746
bool expression_integer_value(expression e, intptr_t *pval)
Definition: eval.c:792
value EvalIntrinsic(entity e, list la)
This function tries to evaluate a call to an intrinsic function.
Definition: eval.c:290
value EvalSyntax(syntax s)
Definition: eval.c:113
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
static bool vect_const_p(Pvecteur v)
returns true if v is not NULL and is constant
Definition: eval.c:1020
int ipow(int vg, int vd)
FI: such a function should exist in Linear/arithmetique.
Definition: eval.c:769
expression normalize_integer_constant_expression(expression e)
Allocate a new expression equivalent to e, but constant expressions are evaluated.
Definition: eval.c:1112
bool expression_negative_integer_value_p(expression e)
Return true iff the expression has an integer value known statically and this value is negative.
Definition: eval.c:814
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 incremen...
Definition: eval.c:979
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
expression make_op_exp(char *op_name, expression exp1, expression exp2)
================================================================
Definition: expression.c:2012
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
bool const_variable_p(entity)
Definition: variable.c:1687
type ultimate_type(type)
Definition: type.c:3466
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
bool scalar_integer_type_p(type)
Definition: type.c:3276
int type_memory_size(type)
Definition: size.c:248
bool unsigned_type_p(type)
Predicates on types.
Definition: type.c:2821
bool float_type_p(type)
Definition: type.c:3263
bool overloaded_type_p(type)
Returns true if t is a variable type with a basic overloaded.
Definition: type.c:2666
#define type_functional_p(x)
Definition: ri.h:2950
#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 syntax_reference_p(x)
Definition: ri.h:2728
#define functional_result(x)
Definition: ri.h:1444
#define value_constant(x)
Definition: ri.h:3073
#define syntax_reference(x)
Definition: ri.h:2730
#define syntax_tag(x)
Definition: ri.h:2727
#define reference_undefined
Definition: ri.h:2302
#define normalized_linear_p(x)
Definition: ri.h:1779
#define call_function(x)
Definition: ri.h:709
#define reference_variable(x)
Definition: ri.h:2326
#define constant_float_p(x)
Definition: ri.h:851
#define sizeofexpression_type(x)
Definition: ri.h:2406
#define range_upper(x)
Definition: ri.h:2290
#define symbolic_constant(x)
Definition: ri.h:2599
#define constant_int(x)
Definition: ri.h:850
#define syntax_call_p(x)
Definition: ri.h:2734
#define sizeofexpression_expression(x)
Definition: ri.h:2409
#define type_functional(x)
Definition: ri.h:2952
@ is_constant_int
Definition: ri.h:817
@ is_constant_litteral
Definition: ri.h:820
@ is_constant_float
Definition: ri.h:818
@ is_value_intrinsic
Definition: ri.h:3034
@ is_value_unknown
Definition: ri.h:3035
@ is_value_constant
Definition: ri.h:3033
@ is_value_code
Definition: ri.h:3031
@ is_value_symbolic
Definition: ri.h:3032
@ 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 range_increment(x)
Definition: ri.h:2292
#define value_constant_p(x)
Definition: ri.h:3071
#define value_symbolic(x)
Definition: ri.h:3070
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define constant_int_p(x)
Definition: ri.h:848
#define expression_undefined
Definition: ri.h:1223
#define entity_name(x)
Definition: ri.h:2790
#define expression_normalized(x)
Definition: ri.h:1249
#define reference_indices(x)
Definition: ri.h:2328
#define syntax_sizeofexpression(x)
Definition: ri.h:2742
#define sizeofexpression_expression_p(x)
Definition: ri.h:2407
#define constant_call_p(x)
Definition: ri.h:860
#define syntax_call(x)
Definition: ri.h:2736
#define range_lower(x)
Definition: ri.h:2288
#define type_undefined
Definition: ri.h:2883
#define constant_float(x)
Definition: ri.h:853
#define call_arguments(x)
Definition: ri.h:711
#define normalized_undefined_p(x)
Definition: ri.h:1746
#define entity_type(x)
Definition: ri.h:2792
#define constant_call(x)
Definition: ri.h:862
#define value_expression_p(x)
Definition: ri.h:3080
#define expression_syntax(x)
Definition: ri.h:1247
#define value_expression(x)
Definition: ri.h:3082
#define entity_initial(x)
Definition: ri.h:2796
#define is_int
Definition: run-time.c:574
#define PLUS
Definition: sc_gram.c:200
Pvecteur vect_multiply(Pvecteur v, Value x)
Pvecteur vect_multiply(Pvecteur v, Value x): multiplication du vecteur v par le scalaire x,...
Definition: scalaires.c:123
#define intptr_t
Definition: stdint.in.h:294
#define MAX(x, y)
Definition: string.c:110
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
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78
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
#define SLASH