PIPS
expression.c
Go to the documentation of this file.
1 /*
2 
3  $Id: expression.c 23625 2020-07-07 06:46:31Z coelho $
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  /* semantic analysis: processing of expressions, with or without
28  * preconditions.
29  *
30  * Expressions in Fortran were assumed to be side effect free most of
31  * the time and transformers were assumed to be linked to statements
32  * only. This is not true in C, where many constructs have side
33  * effects: Consider for instance the following three statements
34  *
35  * n++; j = k = 2; i = j, k = i;
36  *
37  * which may also appear as conditions, initializations or
38  * incrementations in compound statements (while, for, if).
39  *
40  * Most functions here may return transformer_undefined when no
41  * interesting polyhedral approximation exists because the problem
42  * was fixed later at the statement level by using effects. For C, we
43  * need new functions which always succeed. So we need effects at the
44  * expression level although they are not stored in the PIPS
45  * database.
46  *
47  * Moreover, temporary values are used to combine
48  * subexpressions. These temporary values must be projected when a
49  * significant transformer has been obtained, but not earlier. The
50  * temporary value counter cannot be reset before all temporary
51  * variables have been projected (eliminated). So functions which are
52  * called recursively cannot project temporary values and reset the
53  * temporary value counter. We can use wrapping functions and/or an
54  * additional argument, is_internal, to know whether temporary
55  * variables should be eliminated or not when returning the transformer.
56  *
57  * Note that since expressions have side effects, preconditions must
58  * be updated along the left-to-right expression abstraction
59  * process. For example:
60  *
61  * j = 2; i = j + (j = 0) + j;
62  *
63  * but such a case is forbidden by the C99 standard. The result of
64  * the evaluation of such an expression is undefined.
65  */
66 
67 #include <stdio.h>
68 #include <string.h>
69 
70 #include "genC.h"
71 #include "linear.h"
72 
73 #include "misc.h"
74 #include "properties.h"
75 
76 #include "ri.h"
77 #include "effects.h"
78 
79 #include "ri-util.h"
80 #include "prettyprint.h"
81 #include "effects-util.h"
82 
83 #include "text-util.h"
84 
85 #include "effects-simple.h"
86 
87 #include "pips-libs.h"
88 #ifdef HAVE_PIPS_points_to_LIBRARY
89 // for get_points_to_graph_from_statement & expression_to_points_to_sinks
90 #include "points-to.h" // 2 functions
91 #else // no HAVE_PIPS_points_to_LIBRARY
92 // typedef set points_to_graph
95 {
96  pips_internal_error("points-to library not available");
97  return NULL;
98 }
99 
103 {
104  pips_internal_error("points-to library not available");
105  return NIL;
106 }
107 
111 {
112  pips_internal_error("points-to library not available");
113  return NIL;
114 }
115 #endif // HAVE_PIPS_points_to_LIBRARY
116 
117 #include "transformer.h"
118 #include "semantics.h"
119 
120 ␌
121 /* TYPE INDEPENDENT OPERATIONS */
122 
123 /* May return an undefined transformer */
124 // static: no longer because used in ri_to_transformers.c because
125 // assignments are handled here
127  reference r,
128  transformer pre,
129  bool is_internal)
130 {
132  entity rv = reference_variable(r);
133  list sl = reference_indices(r);
134 
135  //FI: we could do better if the subscripts are constants
136  // we could try to use constant_memory_access_path_to_location_entity()
137  // after checking that the reference is constant
138 
139  if(ENDP(sl) && ((!is_internal && analyzable_scalar_entity_p(rv))
140  || entity_has_values_p(rv))) {
141  if(!entity_undefined_p(v)) {
142  entity rv_new = is_internal?
144  transformer tfr = simple_equality_to_transformer(v, rv_new, false);
145  if(!transformer_undefined_p(pre)) {
146  // FI: assume pre is a range
147  tf = transformer_intersection(tfr, pre);
148  }
149  free_transformer(tfr);
150  }
151  }
152  else if(ENDP(sl)) {
153  // Might be a constant value for a pointer, such as "a", an array
155  if(array_type_p(t)) {
156  // int d = (int) gen_length(variable_indices(type_variable(t)));
157  // list sl = make_zero_subscripts(d);
159  reference r = make_reference(rv, sl);
160  entity l = constant_memory_access_path_to_location_entity(r); // l is a constant location
161  if(!entity_undefined_p(l)) {
162  transformer tfr = simple_equality_to_transformer(v, l, false);
163  if(!transformer_undefined_p(pre)) {
164  // FI: assume pre is a range
165  tf = transformer_intersection(tfr, pre);
166  }
167  free_transformer(tfr);
168  }
169  }
170  }
171  else if(get_bool_property("SEMANTICS_ANALYZE_CONSTANT_PATH")) {
173  // an array reference may have an impact on some values
175  if(analyzed_type_p(t)) {
176  bool processed_p = false;
179  if(!entity_undefined_p(rv) && !entity_undefined_p(v)) {
180  processed_p = true;
181  tf = transformer_add_equality(tf, v, rv);
182  }
183  }
184  if(!processed_p) {
185  // FI: not sure why we would only be interested in modified variables
187  FOREACH(ENTITY, wv, wvl) {
188  if(location_entity_p(wv)) {
189  value val = entity_initial(wv);
190  reference lr = value_reference(val);
191  // FI: when a precondition is available, it should be used
192  // to build almost a dependence test
193  if(references_may_conflict_p(r, lr)) {
194  tf = transformer_add_variable_update(tf, wv);
195  }
196  }
197  }
198  }
199  }
200  }
201 
202  if(transformer_undefined_p(tf)) {
203  /* If you are dealing with a C array reference, find transformers
204  for each subscript expression in case of side effects. */
206  if(c_language_module_p(m)) {
208  }
209  }
210  return tf;
211 }
212 ␌
213 static transformer
215  list args,
216  transformer pre,
217  bool minmax,
218  bool is_internal)
219 {
222  list cexpr;
224 
225  pips_debug(8, "begin\n");
226 
227  pips_assert("At least one argument", gen_length(args)>=1);
228 
229  /* pips_assert("Precondition is unused", transformer_undefined_p(pre)); */
230 
231  for(cexpr = args; !ENDP(cexpr); POP(cexpr)) {
232  expression arg = EXPRESSION(CAR(cexpr));
233  type t = entity_type(e);
235  transformer tfe = any_expression_to_transformer(tmp, arg, pre, is_internal);
236 
237  Pvecteur v = vect_new((Variable) tmp, VALUE_ONE);
239 
241 
242  if(minmax) {
243  v = vect_multiply(v, VALUE_MONE);
244  }
245 
246  cv = contrainte_make(v);
247  cv->succ = cl;
248  cl = cv;
249 
250  /* memory leak! */
251  tf_acc = transformer_safe_image_intersection(tf_acc, tfe);
252  }
253 
254 
257 
258  sc_base(sc) = base_add_variable(BASE_NULLE, (Variable) e);
259  sc_dimension(sc) = 1;
260  tf = make_transformer(NIL,
261  make_predicate(sc));
262  }
263  else {
264  /* A miracle occurs and the proper basis is derived from the
265  constraints ( I do not understand why the new and the old value
266  of e both appear... so it may not be necessary for the
267  consistency check... I'm lost, FI, 6 Jan. 1999) */
268  if(!transformer_undefined_p(tf_acc)) {
269  tf_acc = transformer_inequalities_add(tf_acc, cl);
270  }
271  else {
272  /* cl could be kept but would be always projected later */
273  contraintes_free(cl);
274  }
275  tf = tf_acc;
276  }
277 
278  ifdebug(8) {
279  pips_debug(8, "result:\n");
280  dump_transformer(tf);
281  pips_debug(8, "end\n");
282  }
283 
284  return tf;
285 }
286 
287 /* Type independent. Most of it should be factored out for unary operations. */
289  expression e1,
290  transformer pre,
291  bool is_internal)
292 {
295  /* sub-expressions are not necessarily integer? Then the expression
296  should not be integer? */
297  transformer tf1 = any_expression_to_transformer(tmp1, e1, pre, is_internal);
299 
300  pips_debug(9, "Begin for %s\n", entity_local_name(v));
301 
302  tf = transformer_safe_intersection(tf1, tf_op);
303 
304  /* Much too early: you are in between recursive calls! */
305  /* tf = transformer_temporary_value_projection(tf); */
306 
307  free_transformer(tf1);
308  free_transformer(tf_op);
309 
310  pips_debug(9, "End with %p\n", tf);
311  ifdebug(9) dump_transformer(tf);
312 
313  return tf;
314 }
315 
316 /* See also any_basic_update_to_transformer(), which should be based on this function */
318 {
324  list args = list_undefined;
325 
327  inc = int_to_expression(1);
328  else
329  inc = int_to_expression(-1);
330 
331  n_rhs = MakeBinaryCall(plus, inc, entity_to_expression(v));
332 
333  /* FI: why*/
334  args = CONS(EXPRESSION, ve, CONS(EXPRESSION, n_rhs, NIL));
336  args,
338  false);
341  else
342  tf = transformer_add_equality(tf, v, tmp);
343  gen_full_free_list(args);
344 
345  pips_debug(6,"return tf=%p\n", tf);
346  ifdebug(6) (void) dump_transformer(tf);
347  pips_debug(8,"end\n");
348  return tf;
349 }
350 
351 /* forward declaration */
353  entity, expression, transformer, bool);
354 
355 static transformer
357  entity e,
358  entity op,
359  expression e1,
360  transformer pre,
361  bool is_internal)
362 {
364 
365  if(ENTITY_UNARY_MINUS_P(op)) {
366  tf = unary_minus_operation_to_transformer(e, e1, pre, is_internal);
367  }
368  else if(ENTITY_IABS_P(op) || ENTITY_ABS_P(op) || ENTITY_DABS_P(op)
369  || ENTITY_CABS_P(op)
370  || ENTITY_C_ABS_P(op) || ENTITY_LABS_P(op) || ENTITY_LLABS_P(op)
371  || ENTITY_IMAXABS_P(op)
372  || ENTITY_FABS_P(op) || ENTITY_FABSF_P(op) || ENTITY_FABSL_P(op)
373  || ENTITY_C_CABS_P(op) || ENTITY_CABSF_P(op) || ENTITY_CABSL_P(op)) {
374  tf = generic_abs_to_transformer(e, e1, pre, is_internal);
375  }
380 
381  if(entity_has_values_p(v1)) {
383  if(transformer_undefined_p(pre)) {
384  tf = tfu;
385  }
386  else {
387  /* FI: Oops, the precondition is lost here! See any_basic_update_to_transformer() */
388  tf = transformer_combine(transformer_range(pre), tfu);
389  free_transformer(tfu);
390  }
391  }
392  }
393  else if(ENTITY_DEREFERENCING_P(op)) {
395  int n = (int) gen_length(ll);
396 
397  /* And loop over the possible source locations
398  *
399  * A very similar loop is used in lhs_expression_to_transformer()
400  * and in struct_refrence_assignment_to_transformer()...
401  */
403  FOREACH(CELL, cp, ll) {
404  reference r = cell_any_reference(cp); // rhs location
405  // The preconditions may make the convex hull useful when
406  // different locations have known values or are
407  // constrained...
408  transformer rt = copy_transformer(pre);
409 
412  if(!entity_undefined_p(l)) {
413  rt = transformer_add_equality(rt, e, l);
414  }
415  }
416  else {
417  free_transformer(rt);
419  }
420 
421  if (transformer_undefined_p(ntf))
422  ntf = rt;
423  else {
424  if(!transformer_undefined_p(rt)) {
425  ntf = transformer_convex_hull(ntf, rt);
426  free_transformer(rt);
427  }
428  }
429  }
430  tf = ntf;
431  }
432 
433  return tf;
434 }
435 
436 /* Type independent. Most of it should be factored out for binary
437  operations. v = e1 + e2 or v = e1 - e2 */
439  expression e1,
440  expression e2,
441  transformer pre,
442  bool addition_p,
443  bool is_internal)
444 {
446 
447  // FI: the types of subexpressions e1 and e2 should be checked
448  // because they might be pointers or a combination of pointer and
449  // integer. Equations must be adapted by multiplying entities with
450  // sizeof() constants. Not clear how to do this with symbolic
451  // sizeofs used by Nelson to improve portability.
452 
455  /* sub-expressions are not necessarily integer? Then the expression
456  should not be integer? */
457  transformer tf1 = safe_any_expression_to_transformer(tmp1, e1, pre, is_internal);
459  : transformer_apply(tf1, pre);
460  transformer npre = transformer_range(post);
461  transformer tf2 = safe_any_expression_to_transformer(tmp2, e2, npre, is_internal);
463  transformer tf_op = simple_addition_to_transformer(v, tmp1, tmp2, addition_p);
464 
465  free_transformer(post);
466  free_transformer(npre);
467 
468  pips_debug(9, "Begin officialy... but a lot has been done already!\n");
469 
471  tf = transformer_safe_image_intersection(tf12, tf_op);
472 
473  /*
474  ifdebug(9) {
475  pips_debug(9, "before projection, with temporaries v=%s, tmp1=%s, tmp2=%s,"
476  " transformer rf=%p\n",
477  entity_local_name(v), entity_local_name(tmp1),
478  entity_local_name(tmp2), tf);
479  dump_transformer(tf);
480  }
481  */
482 
483  /* Too early: you are projecting v and loosing all useful information
484  within an expression! */
485  /* tf = transformer_temporary_value_projection(tf); */
486 
487  free_transformer(tf2);
488  free_transformer(tf12);
489  free_transformer(tf_op);
490 
491  pips_debug(9, "End with transformer tf=%p\n", tf);
492  ifdebug(9) dump_transformer(tf);
493 
494  return tf;
495 }
496 
497 /* Similar to any_assign_to_transformer(), which is a simpler case. */
498 /* Here, we cope with expression such as the lhs of j = (i=1); */
500  list args, /* arguments for assign */
501  transformer pre, /* precondition */
502  bool is_internal __attribute__ ((unused)))
503 {
505  //transformer tfe = transformer_undefined;
506  expression lhs = EXPRESSION(CAR(args));
507  expression rhs = EXPRESSION(CAR(CDR(args)));
508  syntax slhs = expression_syntax(lhs);
509 
510  pips_assert("2 args to assign", CDR(CDR(args))==NIL);
511 
512  /* The lhs must be a scalar reference to perform an interesting analysis */
513  if(syntax_reference_p(slhs)) {
514  reference rlhs = syntax_reference(slhs);
515  if(ENDP(reference_indices(rlhs))) {
516  entity v = reference_variable(rlhs);
517 
518  if(entity_has_values_p(v)) {
519  entity v_new = entity_to_new_value(v);
520  entity v_old = entity_to_old_value(v);
522 
523  tf = any_expression_to_transformer(tmp2, rhs, pre, true);
524 
525  if(!transformer_undefined_p(tf)) {
526 
527  pips_debug(9, "A transformer has been obtained:\n");
528  ifdebug(9) dump_transformer(tf);
529 
531  /* Is it standard compliant? The assigned variable is
532  modified by the rhs. */
533  transformer teq = simple_equality_to_transformer(v, tmp, true);
534  string s = expression_to_string(rhs);
535 
536  semantics_user_warning("Variable \"%s\" in lhs is uselessly or illegally updated by rhs '%s'\n",
537  entity_user_name(v), s);
538  //entity_local_name(v), s);
539 
540  free(s);
541 
542  tf = transformer_combine(tf, teq);
543  free_transformer(teq);
544  }
545  else {
546  /* Take care of aliasing */
547  entity v_repr = value_to_variable(v_new);
548 
549  /* tf = transformer_value_substitute(tf, v_new, v_old); */
550  tf = transformer_value_substitute(tf, v_new, v_old);
551 
552  pips_debug(9,"After substitution v_new=%s -> v_old=%s\n",
553  entity_local_name(v_new), entity_local_name(v_old));
554 
555  tf = transformer_value_substitute(tf, tmp2, v_new);
556 
557  pips_debug(9,"After substitution tmp=%s -> v_new=%s\n",
558  entity_local_name(tmp2), entity_local_name(v_new));
559 
561  }
562  //tf = generic_equality_to_transformer(tmp, tmp2, false, false);
563  //tf = transformer_combine(tf, tfe);
564  }
565  }
566  }
567  }
568 
569  pips_debug(6,"return tf=%p\n", tf);
570  ifdebug(6) (void) print_transformer(tf);
571  pips_debug(8,"end\n");
572  return tf;
573 }
574 
576  list args, /* arguments for assign */
577  transformer pre, /* precondition */
578  bool is_internal)
579 {
580  transformer tf = any_assign_operation_to_transformer(tmp, args, pre, is_internal);
581  if(transformer_undefined_p(tf)) {
582  // FI: I'd like tmp to appear in the basis...
583  tf = transformer_identity();
584  }
585  return tf;
586 }
587 
588 /* v = (e1 = e1 op e2) ; e1 must be a reference; does not compute
589  information for dereferenced pointers such as in "*p += 2;" */
591  entity op,
592  expression e1,
593  expression e2,
594  transformer pre,
595  bool is_internal)
596 {
598 
599  if(expression_reference_p(e1)) {
600  //transformer utf = transformer_undefined;
603  /* sub-expressions are not necessarily integer? Then the expression
604  should not be integer? */
605  /* We assume that the update operation is syntactically correct */
609  list args = CONS(EXPRESSION, e1, CONS(EXPRESSION, n_exp, NIL));
610 
611  pips_debug(9, "Begin officialy... but a lot has been done already!\n");
612 
613  /* Effects are used at a higher level */
614  tf = any_assign_operation_to_transformer(v, args, /* ef,*/ pre, is_internal);
615  gen_free_list(args);
616  free_expression(n_exp);
617 
618  if(!transformer_undefined_p(tf))
619  tf = transformer_add_equality(tf, v, v1);
620 
621  ifdebug(8) {
622  pips_debug(8, "before projection, with temporaries v=%s, tmp1=%s, tmp2=%s,"
623  " transformer rf=%p\n",
625  entity_local_name(tmp2), tf);
626  dump_transformer(tf);
627  }
628 
629  /* Too early: you are projecting v and loosing all useful information
630  within an expression! */
631  /* tf = transformer_temporary_value_projection(tf); */
632 
633  //free_transformer(tf2);
634  //free_transformer(tf12);
635  //free_transformer(tf12u);
636  //free_transformer(tf_op);
637  }
638 
639  pips_debug(8, "End with transformer tf=%p\n", tf);
640  ifdebug(8) dump_transformer(tf);
641 
642  return tf;
643 }
644 ␌
646  expression rhs)
647 {
649  syntax srhs = expression_syntax(rhs);
650 
651  pips_debug(9, "Begin for entity %s",
652  entity_local_name(v));
653 
654  /* the rhs is a call to a constant function */
655  if(syntax_call_p(srhs)) {
657 
658  pips_debug(9, " and constant %s\n", module_local_name(f));
659 
660  if(entity_constant_p(f)) {
661  basic fb = entity_basic(f);
662 
663  if(basic_string_p(fb)) {
664  basic vb = entity_basic(v);
665  if(basic_string_p(vb)) {
666  int llhs = string_type_size(vb);
667  int lrhs = string_type_size(fb);
668 
669  if(llhs==-1 || llhs >= lrhs) {
670  /* Implicitly sufficient length or implicit padding with SPACEs */
671  tf = simple_equality_to_transformer(v, f, false);
672  }
673  else {
674  /* Take the prefix of the constant. Expect problems with PIPS quotes... */
675  string n = malloc(llhs+3);
677 
678  n = strncpy(n, entity_local_name(f), llhs+1);
679  *(n+llhs+1) = *n;
680  pips_assert("A simple or a double quote is used", *n=='"' || *n=='\'');
681  *(n+llhs+2) = 0;
682  f1 = make_constant_entity(n, is_basic_string, llhs);
683  tf = simple_equality_to_transformer(v, f1, false);
684  }
685  }
686  else {
687  pips_user_error("CHARACTER variable assigned a non CHARACTER constant, \"%s\"\n",
689  }
690  }
691  else {
692  /* This is not a constant string */
693  int i;
694  if(integer_constant_p(f, &i) && i==0) {
695  tf = transformer_identity();
697  }
698  else if(float_constant_p(f) && float_constant_to_double(f)==0.) {
699  tf = transformer_identity();
701  }
702  else
703  tf = simple_equality_to_transformer(v, f, false);
704  }
705  }
706  }
707 
708  pips_debug(9, "End for entity %s\n",
709  entity_local_name(v));
710 
711  return tf;
712 }
713 ␌
714 /* HANDLING OF CONDITIONS */
715 
716 # define DEBUG_TRANSFORMER_ADD_CONDITION_INFORMATION_UPDOWN 7
717 
718 /* call transformer_add_condition_information_updown() recursively
719  * on both sub-expressions if veracity == true; else
720  * try your best...
721  *
722  */
724 (transformer, expression, transformer, bool, bool);
725 
726 static transformer
728  transformer pre,
729  expression c1,
730  expression c2,
732  bool veracity,
733  bool upwards)
734 {
736 
737  pips_debug(9,"Begin with pre=%p, veracity=%s, upwards=%s\n,",
738  pre, bool_to_string(veracity),
739  bool_to_string(upwards));
740 
741  if(veracity) {
742  /* FI: this is a bit confusing because of aliasing conditions.
743  * The second condition is added after the first one was analyzed
744  * and the "and" effect is enforced by side effect
745  *
746  * This is equivalent to allocating copies of pre and then computing
747  * their intersection.
748  */
750  ifdebug(9) {
751  pips_debug(9, "pre=%p:\n", pre);
752  dump_transformer(pre);
753  }
754 
756  (pre, c1, context, veracity, upwards);
757 
758  ifdebug(9) {
759  pips_debug(9, "pre1=%p:\n", pre1);
760  dump_transformer(pre1);
761  }
762 
764  (pre1, c2, context, veracity, upwards);
765 
766  ifdebug(9) {
767  pips_debug(9, "newpre=%p:\n", newpre);
768  dump_transformer(newpre);
769  }
770  }
771  else if(!upwards || upwards) { /* This is useful when computing transformers in context */
772  /* use precondition pre and hope than the convex hull won't destroy
773  all information */
774  /* compute !(c1&&c2) as !c1 || !c2 */
775  transformer pre1 = transformer_dup(pre);
776  transformer pre2 = pre;
777 
779  (pre1, c1, context, false, upwards);
781  (pre2, c2, context, false, upwards);
782  newpre = transformer_convex_hull(pre1, pre2);
783 
786  "pre1 =\n");
787  dump_transformer(pre1);
789  "pre2 =\n");
790  dump_transformer(pre2);
792  "newpre =\n");
793  dump_transformer(newpre);
794  }
795  free_transformer(pre1);
796  free_transformer(pre2);
797  }
798  else {
799  /* might be possible to add a convex hull on the initial values
800  * as in !upwards
801  */
802  newpre = pre;
803  }
804 
805  ifdebug(9) {
806  pips_debug(9, "end with newpre=%p\n", newpre);
807  dump_transformer(newpre);
808  }
809 
810  return newpre;
811 }
812 
813 /* call transformer_add_condition_information_updown() recursively on both
814  * sub-expressions if veracity == false; else try to do your best...
815  *
816  * Should be fused with the .AND. case?!? Careful with veracity...
817  *
818  */
819 
821  transformer pre,
822  expression c1,
823  expression c2,
825  bool veracity,
826  bool upwards)
827 {
829 
830  pips_debug(9,"Begin with pre=%p, context=%p, veracity=%s, upwards=%s\n,",
831  pre, context, bool_to_string(veracity),
832  bool_to_string(upwards));
833 
834  if(!veracity) {
835  /* compute !(c1||c2) as !c1 && !c2 */
837  (pre, c1, context, false, upwards);
839  (newpre, c2, context, false, upwards);
840  }
841  else if(!upwards) {
842  /* compute (c1||c2) as such */
843  transformer pre1 = transformer_dup(pre);
844  transformer pre2 = pre;
845 
847  (pre1, c1, context, true, upwards);
849  (pre2, c2, context, true, upwards);
850  newpre = transformer_convex_hull(pre1, pre2);
851 
854  "pre1 =\n");
855  (void) (void) dump_transformer(pre1);
857  "pre2 =\n");
858  (void) dump_transformer(pre2);
860  "newpre =\n");
861  (void) (void) dump_transformer(newpre);
862  }
863 
864  free_transformer(pre1);
865  free_transformer(pre2);
866  }
867  else {
868  /* might be possible to add a convex hull on the initial values
869  * as in !upwards
870  */
871  newpre = pre;
872  }
873 
874  ifdebug(9) {
875  pips_debug(9, "end with newpre=%p\n", newpre);
876  dump_transformer(newpre);
877  }
878 
879  return newpre;
880 }
881 
883  transformer pre,
884  entity op,
885  list args,
887  bool veracity,
888  bool upwards)
889 {
893 
894  pips_debug(9,"Begin with pre=%p, op=%s, veracity=%s, upwards=%s\n,",
895  pre, module_local_name(op), bool_to_string(veracity),
896  bool_to_string(upwards));
897 
898  if(!ENDP(args)) {
899  c1 = EXPRESSION(CAR(args));
900  if(!ENDP(CDR(args))) {
901  c2 = EXPRESSION(CAR(CDR(args)));
902  }
903  }
904 
906  newpre = transformer_add_any_relation_information(pre, op, c1, c2, context,
907  veracity, upwards);
908  }
909  else if(ENTITY_AND_P(op)) {
911  (pre, c1, c2, context, veracity, upwards);
912  }
913  else if(ENTITY_OR_P(op)) {
915  (pre, c1, c2, context, veracity, upwards);
916  }
917  else if(ENTITY_NOT_P(op)) {
919  (pre, c1, context, !veracity, upwards);
920  }
921  else if(((ENTITY_TRUE_P(op) || ENTITY_ONE_P(op)) && !veracity) ||
922  ((ENTITY_FALSE_P(op) || ENTITY_ZERO_P(op)) && veracity)) {
923  free_transformer(pre);
924  newpre = transformer_empty();
925  }
926  else {
927  /* do not know what to do with other logical operators, for the
928  * time being! keep pre unmodified
929  *
930  * FI: two problems, you can bump into arithmetic operators and
931  * you can have side effects as in i++
932  */
933  /* Minimal service: use effects */
934  newpre = pre;
935  FOREACH(EXPRESSION, a, args) {
937  newpre = transformer_combine(tf, newpre);
938  }
939  }
940 
941  ifdebug(9) {
942  pips_debug(9, "end with newpre=%p\n", newpre);
943  dump_transformer(newpre);
944  }
945 
946  return newpre;
947 }
948 
949 /* Non-convex information can be made convex when moving postcondition downwards
950  * because some of the parts introducing non-convexity may be made empty by
951  * the pre-existing precondition.
952  *
953  * This is not true for transformers computed upwards, although conditions on
954  * initial values could also be added. Let's wait for a case which would prove
955  * this useful.
956  *
957  * Argument pre is modified and may or not be returned as newpre. It may also be
958  * freed and newpre allocated. In other words, argument "pre" should not be used
959  * after a call to this function and the returned value alswayd used.
960  */
962  transformer pre,
963  expression c,
965  bool veracity,
966  bool upwards)
967 {
968  /* default option: no condition can be added */
969  transformer newpre = pre;
970  syntax s = expression_syntax(c);
971 
974  "begin upwards=%s veracity=%s c=",
975  bool_to_string(upwards), bool_to_string(veracity));
976  print_expression(c);
977  (void) fprintf(stderr,"pre=%p\n", pre);
978  dump_transformer(pre);
979  (void) fprintf(stderr,"and context=%p\n", context);
981  }
982 
983  switch(syntax_tag(s)){
984  case is_syntax_call:
985  {
987  // FI: for the time being, I do not use ultimate_type()
990  if(basic_overloaded_p(cb)) {
991  type ert = expression_to_type(c);
993  }
994 
996  list args = call_arguments(syntax_call(s));
997 
999  (pre, f, args, context, veracity, upwards);
1000  }
1001  else if(basic_int_p(cb)) {
1002  if(( ENTITY_ONE_P(f) && !veracity) ||
1003  (ENTITY_ZERO_P(f) && veracity)) {
1004  free_transformer(pre);
1005  newpre = transformer_empty();
1006  }
1007  else {
1009  transformer ct =
1011  if(!veracity)
1013  newpre = transformer_apply(ct, pre);
1014  free_transformer(ct);
1015  free_transformer(pre);
1016  }
1017  }
1018  else {
1020  newpre = transformer_apply(tf, pre);
1021  free_transformer(tf);
1022  free_transformer(pre);
1023  }
1024  free_basic(cb);
1025  break;
1026  }
1027  case is_syntax_reference:
1028  {
1029  /* A logical variable must be referenced in Fortran. Any
1030  variable can be referenced in C. */
1032  if(entity_has_values_p(l)) {
1033  entity l_new = entity_to_new_value(l);
1034  type lt = ultimate_type(entity_type(l));
1036 
1037  if(basic_logical_p(lb)) {
1038  Pvecteur eq = vect_new((Variable) l_new, VALUE_ONE);
1039 
1040  if(veracity) {
1042  }
1043 
1044  newpre = transformer_equality_add(pre, eq);
1045  }
1046  else {
1047  Pvecteur eq = vect_new((Variable) l_new, VALUE_ONE);
1048 
1049  if(veracity) {
1052  }
1053  newpre = transformer_inequality_add(pre, eq);
1054  }
1055  }
1056  break;
1057  }
1058  case is_syntax_range:
1059  {
1060  pips_internal_error("range used as test condition!");
1061  break;
1062  }
1063  case is_syntax_subscript:
1064  {
1065  /* information may be lost */
1066  newpre = pre;
1067  break;
1068  }
1069  case is_syntax_cast:
1070  {
1071  /* ignore cast (should be a boolean cast...) */
1072  cast cce = syntax_cast(s);
1073  expression ce = cast_expression(cce);
1074  newpre =
1076  veracity, upwards);
1077  break;
1078  }
1079  default:
1080  pips_internal_error("ill. expr. as test condition");
1081  }
1082 
1085  "end newpre=%p\n", newpre);
1086  dump_transformer(newpre);
1087  }
1088 
1089  return newpre;
1090 }
1091 ␌
1093  transformer pre,
1094  expression c,
1096  bool veracity)
1097 {
1098  transformer post =
1100  veracity, true);
1101 
1104 
1105  return post;
1106 }
1107 
1108 /* context might be derivable from pre as transformer_range(pre) but this
1109  is sometimes very computationally intensive, e.g. in ocean. */
1112  transformer pre,
1113  expression c,
1115  bool veracity)
1116 {
1118 
1122  (pre, c, context, veracity, false);
1123  }
1124  else {
1125  transformer new_context = transformer_range(context);
1126 
1128  (pre, c, new_context, veracity, false);
1129  free_transformer(new_context);
1130  }
1131 
1134 
1135  return post;
1136 }
1137 
1139  expression c,
1141  bool veracity)
1142 {
1143  tf = transformer_add_condition_information(tf, c, context, veracity);
1144  return tf;
1145 }
1146 
1148  expression c,
1150  bool veracity)
1151 {
1152  tf = precondition_add_condition_information(tf, c, context, veracity);
1153  return tf;
1154 }
1155 ␌
1156 /* INTEGER EXPRESSIONS */
1157 
1158 /* FI: I do no longer understand the semantics of
1159  "is_internal"... although I designed it. The intent was probably to
1160  manage temporary values: they should be preserved as long as the
1161  analysis is internal and else projected.
1162 
1163  Furthermore, this function is no longer very useful as
1164  normalization can be performed dynamically again and again at a low
1165  cost.
1166  */
1168 {
1170  Pvecteur ve = vect_new((Variable) e, VALUE_ONE);
1171  Pvecteur vexpr = vect_dup(a);
1172  Pcontrainte c;
1174 
1175  pips_debug(8, "begin with is_internal=%s\n", bool_to_string(is_internal));
1176 
1177  ifdebug(9) {
1178  pips_debug(9, "\nLinearized expression:\n");
1179  vect_dump(vexpr);
1180  }
1181 
1182  /* The renaming from variables in a to new values in ve and vexpr is
1183  * performed as a side-effect by
1184  * value_mappings_compatible_vector_p() which fails when a
1185  * renaming fails.
1186  *
1187  * This is very dangerous when is_internal==false
1188  */
1189  if(!is_internal
1192  eq = vect_substract(ve, vexpr);
1193  vect_rm(ve);
1194  vect_rm(vexpr);
1195  c = contrainte_make(eq);
1196  tf = make_transformer(NIL,
1198  }
1199  else {
1200  vect_rm(eq);
1201  vect_rm(ve);
1202  vect_rm(vexpr);
1203  tf = transformer_undefined;
1204  }
1205 
1206  pips_debug(8, "end with tf=%p\n", tf);
1207  ifdebug(8) dump_transformer(tf);
1208 
1209  return tf;
1210 }
1211 
1213 {
1215  Pvecteur ve = vect_new((Variable) e, VALUE_ONE);
1216  entity e_new = entity_to_new_value(e);
1217  entity e_old = entity_to_old_value(e);
1218  cons * tf_args = CONS(ENTITY, e_new, NIL);
1219  /* must be duplicated right now because it will be
1220  renamed and checked at the same time by
1221  value_mappings_compatible_vector_p() */
1222  Pvecteur vexpr = vect_dup(a);
1223  Pcontrainte c;
1225 
1226  pips_debug(8, "begin\n");
1227 
1228  ifdebug(9) {
1229  pips_debug(9, "\nLinearized expression:\n");
1230  vect_dump(vexpr);
1231  }
1232 
1233  if(!assignment) {
1234  vect_add_elem(&vexpr, (Variable) e, (Value) 1);
1235 
1236  ifdebug(8) {
1237  pips_debug(8, "\nLinearized expression for incrementation:\n");
1238  vect_dump(vexpr);
1239  }
1240  }
1241 
1244  ve = vect_variable_rename(ve,
1245  (Variable) e,
1246  (Variable) e_new);
1247  (void) vect_variable_rename(vexpr,
1248  (Variable) e_new,
1249  (Variable) e_old);
1250  eq = vect_substract(ve, vexpr);
1251  vect_rm(ve);
1252  vect_rm(vexpr);
1253  c = contrainte_make(eq);
1254  tf = make_transformer(tf_args,
1256  }
1257  else {
1258  vect_rm(eq);
1259  vect_rm(ve);
1260  vect_rm(vexpr);
1261  tf = transformer_undefined;
1262  }
1263 
1264  pips_debug(8, "end\n");
1265 
1266  return tf;
1267 }
1268 
1270 {
1272 
1273  tf = affine_to_transformer(e, a, false);
1274 
1275  return tf;
1276 }
1277 ␌
1278 static transformer modulo_of_a_constant_to_transformer(entity e, int lb1, int lb2, int ub2)
1279 {
1280  /* Since arg1 is a constant, ub1=lb1 */
1282 
1283  /* The first argument is numerically known */
1284  if(lb1==0) {
1285  /* r == 0 not matter what */
1287  }
1288  else if(lb2==ub2) {
1289  if(lb2==0) {
1290  /* A floating point exception is going to be raised */
1291  semantics_user_warning("Zero divide encountered\n");
1292  tf3 = transformer_empty();
1293  }
1294  else {
1295  /* The result is known: r = lb1 % lb2 if lb2!=0 */
1296  int r = lb1 % lb2;
1298  }
1299  }
1300  else if(ub2<0) {
1301  /* The second argument is negative:
1302  * lb1>0? r>=0, r<= ub1, r<=-lb2-1
1303  * : r<=0, -ub1<=r, r>= lb2+1 */
1304  if(lb1>0) {
1305  if(lb1<-ub2) {
1306  /* the modulo has no impact r=ub1=lb1 */
1308  }
1309  else {
1310  /* r>=0, r<= ub1, r<=-lb2-1 */
1312  e, 0, false);
1313  tf3 = transformer_add_inequality_with_integer_constraint(tf3, e, lb1, true);
1314  tf3 = transformer_add_inequality_with_integer_constraint(tf3, e, -lb2-1, true);
1315  }
1316  }
1317  else {
1318  if(lb1>ub2) {
1319  /* the modulo has no impact r=ub1=lb1 */
1321  }
1322  else {
1323  /* r<=0, -ub1<=r, r>= lb2+1 */
1325  e, 0, true);
1326  tf3 = transformer_add_inequality_with_integer_constraint(tf3, e, lb1, false);
1327  tf3 = transformer_add_inequality_with_integer_constraint(tf3, e, lb2+1, false);
1328  }
1329  }
1330  }
1331  else if(lb2>0) {
1332  /* The second argument is positive:
1333  * lb1>0? r>=0, r<= ub1, r<=ub2-1
1334  * : r<=0, -ub1<=r, -ub2+1<=r
1335  */
1336  if(lb1>0) {
1337  if(lb1<lb2) {
1338  /* the modulo has no impact r=ub1=lb1 */
1340  }
1341  else {
1342  /* r>=0, r<= ub1, r<=-lb2-1 */
1343  /* r>=0, r<= ub1, r<=ub2-1 */
1345  e, 0, false);
1346  tf3 = transformer_add_inequality_with_integer_constraint(tf3, e, lb1, true);
1347  tf3 = transformer_add_inequality_with_integer_constraint(tf3, e, ub2-1, true);
1348  }
1349  }
1350  else {
1351  if(-lb1<ub2) {
1352  /* the modulo has no impact r=ub1=lb1 */
1354  }
1355  else {
1356  /* r<=0, -ub1<=r, -ub2+1<=r */
1358  e, 0, true);
1359  tf3 = transformer_add_inequality_with_integer_constraint(tf3, e, lb1, false);
1360  tf3 = transformer_add_inequality_with_integer_constraint(tf3, e, -ub2+1, false);
1361  }
1362  }
1363  }
1364  else {
1365  /* no information is available on the second argument: the
1366  sign of the first argument is preserved */
1368  e, 0, lb1<0);
1369  }
1370  return tf3;
1371 }
1372 
1373 /* e = [lb1,ub1] % [lb2,ub2] with ub1<=0 */
1375  int lb1, int ub1,
1376  int lb2, int ub2)
1377 {
1379  /* arg1 is negative, hence r is always negative: r<=0 */
1380  if(ub2<0) {
1381  if(ub2<lb1) {
1382  /* the modulo is the identity: lb1<=r<=ub1*/
1384  e, lb1, false);
1386  e, ub1, true);
1387  }
1388  else {
1389  /* arg2 is negative: r>=arg2, r>= lb2+1 */
1391  e, 0, true);
1393  e, lb2+1, false);
1394  }
1395  }
1396  else if(lb2>0) {
1397  if(lb2>-ub1) {
1398  /* the modulo is the identity: lb1<=r<=ub1 */
1399  if(lb1>INT_MIN)
1401  e, lb1, false);
1402  else
1403  tf3 = transformer_identity();
1405  e, ub1, true);
1406  }
1407  else {
1408  /* arg2 is positive: r<=-arg2+1, r<= -lb2+1 */
1410  e, 0, true);
1412  e, -lb2+1, true);
1413  }
1414  }
1415  else {
1416  /* No information is available on arg2: r<=0 */
1418  e, 0, true);
1419  }
1420 
1421  return tf3;
1422 }
1423 
1425  int lb1, int ub1,
1426  int lb2, int ub2)
1427 {
1429  /* arg1 is positive, hence r is always positive: r>=0 */
1430  if(ub2<0) {
1431  if(-ub2>ub1) {
1432  /* the modulo is the identity: lb1<=r<=ub1 */
1434  e, lb1, false);
1436  e, ub1, true);
1437  }
1438  else {
1439  /* arg2 is negative: 0<=r<=-arg2+1, 0<=r<= -ub2+1 */
1441  e, 0, false);
1443  e, -ub2+1, true);
1444  }
1445  }
1446  else if(lb2>0) {
1447  if(lb2>ub1) {
1448  /* the modulo is the identity: lb1<=r<=ub1*/
1450  e, lb1, false);
1452  e, ub1, true);
1453  }
1454  else {
1455  /* arg2 is positive: 0<=r<=arg2-1, 0<=r<= ub2-1 */
1457  e, 0, false);
1459  e, ub2-1, true);
1460  }
1461  }
1462  else {
1463  /* No information is available on arg2: r>=0 */
1465  e, 0, false);
1466  }
1467 
1468  return tf3;
1469 }
1470 
1471 /* Analyze v2 % k, with v2 constrainted by tf, assuming tf is a precondition
1472  *
1473  * See if exist a set v_i such that v2 = sum_i a_i v_i + c. Then v2 can
1474  * be rewritten as v2 = gcd_i(a_i) lambda + c.
1475  *
1476  * if k divides gcd(a_i) then v2>0 ? v1 = v2 % k = c % k : v1 = v2 % k = c%k-k
1477  *
1478  * If the sign of v2 is unknown, c%k-k<=v1<=c%k
1479  *
1480  */
1482 {
1484  Value gcd, c, K = (Value) k;
1485 
1486  // exists lambda s.t. v2 = lambda gcd + c ^ 0<=c<gcd
1487  if(transformer_to_1D_lattice(v2, prec, &gcd, &c)) {
1488 
1489  // The sign of gcd does not matter more than the sign of lambda
1490  if(gcd<0) gcd = -gcd;
1491 
1492  // Is v2's sign known ?
1493  // Adding the sign constraint and using LP might be more efficient
1494  bool is_positive_p = false;
1495  bool is_negative_p = false;
1496  intptr_t imin = 0, imax = 0;
1497 
1498  if (precondition_minmax_of_value(v2, prec, &imin, &imax)) {
1499  is_positive_p = imin>=0;
1500  is_negative_p = imax<=0;
1501  }
1502 
1503  if (imin==imax) {
1504  // This piece of code should be useless because we expect
1505  // gcd = 0 and c = imin = imax in such a case
1506  // But it fails with Semantics-New/modulo16.c
1507  mtf = transformer_add_equality_with_integer_constant(mtf, v1, imin%K);
1508  }
1509  else if (gcd!=0) {
1510  if(gcd%k==0) {
1511  if(is_positive_p)
1513  else if(is_negative_p)
1514  mtf = transformer_add_equality_with_integer_constant(mtf, v1, c%K-K);
1515  else {
1516  mtf = transformer_add_inequality_with_integer_constraint(mtf, v1, c%K, true);
1517  mtf = transformer_add_inequality_with_integer_constraint(mtf, v1, c%K-K, false);
1518  }
1519  }
1520  else {
1521  if(is_positive_p) {
1522  mtf = transformer_add_inequality_with_integer_constraint(mtf, v1, K-1, true);
1523  mtf = transformer_add_inequality_with_integer_constraint(mtf, v1, 0, false);
1524  }
1525  else if(is_negative_p) {
1527  mtf = transformer_add_inequality_with_integer_constraint(mtf, v1, -K+1, false);
1528  }
1529  else {
1530  mtf = transformer_add_inequality_with_integer_constraint(mtf, v1, K-1, true);
1531  mtf = transformer_add_inequality_with_integer_constraint(mtf, v1, -K+1, false);
1532  }
1533  }
1534  }
1535  else { // Same result
1536  // v2 = c
1537  if(is_positive_p)
1539  else if(is_negative_p)
1540  mtf = transformer_add_equality_with_integer_constant(mtf, v1, c%K-K);
1541  else {
1542  mtf = transformer_add_inequality_with_integer_constraint(mtf, v1, c%K, true);
1543  mtf = transformer_add_inequality_with_integer_constraint(mtf, v1, c%K-K, false);
1544  }
1545  }
1546  }
1547  else {
1548  // There is no solution. E.g. v2==2 ^ v2==1 or 0==1
1549  // This case should be detected earlier and this piece of code is
1550  // probably unreachable
1551  mtf = empty_transformer(mtf);
1552  }
1553  return mtf;
1554 }
1555 
1556 /* Modulo and integer division
1557  *
1558  * Apparently identical in both C and Fortran
1559  *
1560  * C Fortran
1561  * a b mod div mod div
1562  * 3 2 1 1 1
1563  * -3 2 -1 -1 -1
1564  * 3 -2 1 -1 1
1565  * -3 -2 -1 1 -1
1566  *
1567  * FI: only implemented for positive dividends. Same for integer
1568  * division, I believe. Side effects are probably ignored.
1569  *
1570  * FI: to be improved by using expression_to_transformer() and the
1571  * precondition pre.
1572  *
1573  * FI: to be improved by using the lattice information in the
1574  * equations of the precondition.
1575  *
1576  * matrice_hermite()
1577  *
1578  * sc_to_matrices()
1579  */
1580 static transformer modulo_to_transformer(entity e, /* assumed to be an integer value */
1581  expression arg1,
1582  expression arg2,
1583  transformer pre, /* not used yet */
1584  bool is_internal __attribute__ ((unused)))
1585 {
1588  transformer tf1 = safe_any_expression_to_transformer(v1, arg1, pre, true);
1589  transformer npre =
1591  transformer pre2 = transformer_range(npre);
1593  transformer tf2 = safe_any_expression_to_transformer(v2, arg2, pre2, true);
1594  npre = transformer_apply(tf2, pre2);
1595  transformer pre3 = transformer_range(npre);
1596  // To be cleaned up later
1597  //transformer tf3 = transformer_undefined;
1599 
1600  pips_debug(8, "begin with pre=%p\n", pre);
1601 
1602  /* cut-and-pasted and adapted from multiply_to_transformer(); also useful for
1603  divide; the side effects of the two arguments and the derivation
1604  of the preconditions and the computation of the numerical bounds
1605  should be factorized in one function. */
1606  if(!transformer_undefined_p(pre) && !transformer_undefined_p(npre)) {
1607  int lb1 = 0;
1608  int ub1 = 0;
1609  int lb2 = 0;
1610  int ub2 = 0;
1611  expression ev1 = entity_to_expression(v1);
1612  expression ev2 = entity_to_expression(v2);
1613 
1614  expression_and_precondition_to_integer_interval(ev1, pre2, &lb1, &ub1);
1615  expression_and_precondition_to_integer_interval(ev2, pre3, &lb2, &ub2);
1616  free_expression(ev1);
1617  free_expression(ev2);
1618 
1619  if(lb2==ub2) {
1620  if(ub2==0) {
1621  /* Let's get rid of the exception case right away */
1622  /* A floating point exception is going to be raised */
1623  semantics_user_warning("Zero divide encountered\n");
1624  tf3 = transformer_empty();
1625  }
1626  else {
1627  // lb2==ub2!=0
1628  // FI: we might have to impose lb2>0
1629  // FI: let's assume that pre is carried by tf1
1630  tf3 = modulo_by_a_constant_to_transformer(e, tf1, v1, lb2);
1631  }
1632  }
1633 
1634  if(transformer_identity_p(tf3)) {
1635  free_transformer(tf3);
1636  if(lb1==ub1) {
1637  tf3 = modulo_of_a_constant_to_transformer(e, lb1, lb2, ub2);
1638  }
1639  else if(ub1<=0) {
1640  tf3 = modulo_of_a_negative_value_to_transformer(e, lb1, ub1, lb2, ub2);
1641  }
1642  else if(lb1>=0) {
1643  tf3 = modulo_of_a_positive_value_to_transformer(e, lb1, ub1, lb2, ub2);
1644  }
1645  else {
1646  /* No sign information available about arg1 */
1647  if(lb2>0) {
1648  /* arg2 is positive: -ub2+1<=r<=ub2-1 */
1650  e, -ub2+1, false);
1652  e, ub2-1, true);
1653  }
1654  else if(ub2<0) {
1655  /* arg2 is negative: lb2+1<=r<=-lb2-1 */
1657  e, lb2+1, false);
1659  e, -lb2-1, true);
1660  }
1661  else
1662  tf3 = transformer_identity();
1663  }
1664  }
1665  }
1666  else {
1667  /* Might be as good to leave it undefined... for the time
1668  being. Information about either arg1 or arg2 could be used */
1669  tf3 = transformer_identity();
1670  ;
1671  }
1672 
1673 
1674  /* Take care of side effects: tf = tf1 o tf2 o tf3 */
1675  tf = transformer_combine(tf1, tf2);
1676  tf = transformer_combine(tf, tf3);
1677  free_transformer(tf2);
1678  free_transformer(tf3);
1679 
1680  free_transformer(pre2);
1681  free_transformer(pre3);
1682  free_transformer(npre);
1683 
1684  ifdebug(8) {
1685  pips_debug(8, "result:\n");
1686  dump_transformer(tf);
1687  pips_debug(8, "end\n");
1688  }
1689 
1690  return tf;
1691 }
1692 ␌
1693 static transformer iabs_to_transformer(entity v, /* assumed to be a value */
1694  expression expr,
1695  transformer pre,
1696  bool is_internal)
1697 {
1700  transformer etf = integer_expression_to_transformer(tv, expr, pre, is_internal);
1701  Pvecteur vlb1 = vect_new((Variable) tv, VALUE_ONE);
1702  Pvecteur vlb2 = vect_new((Variable) tv, VALUE_MONE);
1703 
1704  pips_debug(8, "begin\n");
1705 
1706 
1707  vect_add_elem(&vlb1, (Variable) v, VALUE_MONE);
1708  vect_add_elem(&vlb2, (Variable) v, VALUE_MONE);
1709 
1710  tf = transformer_inequality_add(tf, vlb1);
1711  tf = transformer_inequality_add(tf, vlb2);
1713  free_transformer(etf);
1714 
1715  ifdebug(8) {
1716  pips_debug(8, "result:\n");
1717  dump_transformer(tf);
1718  pips_debug(8, "end\n");
1719  }
1720 
1721  return tf;
1722 }
1723 
1724 /* Copy of iabs_to_transformer(), which is probably never called anymore */
1725 static transformer generic_abs_to_transformer(entity v, /* assumed to be a value */
1726  expression expr,
1727  transformer pre,
1728  bool is_internal)
1729 {
1731  /* Expression expr may be of a type different from v's type because
1732  abs maybe generic and because type conversions may be implicit */
1734  type et = expression_to_type(expr);
1735  transformer etf = any_expression_to_transformer(tv, expr, pre, is_internal);
1736  int lb=INT_MIN, ub=INT_MAX;
1737 
1738  pips_debug(8, "begin\n");
1739 
1740  if(integer_type_p(et))
1742  free_type(et);
1743 
1744  if(ub==lb) {
1746  }
1747  else if(lb>=0) {
1748  tf = transformer_add_equality(tf, v, tv);
1749  }
1750  else if(ub<=0) {
1753  }
1754  else {
1755  Pvecteur vlb1 = vect_new((Variable) tv, VALUE_ONE);
1756  Pvecteur vlb2 = vect_new((Variable) tv, VALUE_MONE);
1757 
1758 
1759  vect_add_elem(&vlb1, (Variable) v, VALUE_MONE);
1760  vect_add_elem(&vlb2, (Variable) v, VALUE_MONE);
1761 
1762  tf = transformer_inequality_add(tf, vlb1);
1763  tf = transformer_inequality_add(tf, vlb2);
1764  }
1765 
1767  free_transformer(etf);
1768 
1769  ifdebug(8) {
1770  pips_debug(8, "result:\n");
1771  dump_transformer(tf);
1772  pips_debug(8, "end\n");
1773  }
1774 
1775  return tf;
1776 }
1777 ␌
1778 /* More could be done along the line of
1779  integer_multiply_to_transformer()... when need arises.*/
1781  expression arg1,
1782  expression arg2,
1783  transformer pre,
1784  bool is_internal)
1785 {
1787  normalized n1 = NORMALIZE_EXPRESSION(arg1);
1788 
1789  pips_debug(8, "begin with is_internal=%s\n",
1790  bool_to_string(is_internal));
1791 
1792  /* pips_assert("Precondition is unused", transformer_undefined_p(pre)); */
1793  pips_assert("Shut up the compiler", pre==pre);
1794 
1797  int d = integer_constant_expression_value(arg2);
1798  /* must be duplicated right now because it will be
1799  renamed and checked at the same time by
1800  value_mappings_compatible_vector_p() */
1801  Pvecteur vlb =
1803  Pvecteur vub = vect_dup(normalized_linear(n1));
1806 
1807  vect_add_elem(&vlb, (Variable) e, int_to_value(d));
1808  vect_add_elem(&vub, (Variable) e, int_to_value(-d));
1809  vect_add_elem(&vub, TCST, int_to_value(1-d));
1810  clb = contrainte_make(vlb);
1811  cub = contrainte_make(vub);
1812  clb->succ = cub;
1813  tf = make_transformer(NIL,
1815  }
1816 
1817  ifdebug(8) {
1818  pips_debug(8, "result:\n");
1819  dump_transformer(tf);
1820  pips_debug(8, "end\n");
1821  }
1822 
1823  return tf;
1824 }
1825 /* More could be done along the line of
1826  integer_left_shift_to_transformer()... when need arises.*/
1828  expression arg1,
1829  expression arg2,
1830  transformer pre,
1831  bool is_internal)
1832 {
1834  normalized n1 = NORMALIZE_EXPRESSION(arg1);
1835 
1836  pips_debug(8, "begin with is_internal=%s\n",
1837  bool_to_string(is_internal));
1838 
1839  /* pips_assert("Precondition is unused", transformer_undefined_p(pre)); */
1840  pips_assert("Shut up the compiler", pre==pre);
1841 
1844  int d = integer_constant_expression_value(arg2);
1845  Value val = value_lshift((Value) 1, (Value) d);
1846  /* must be duplicated right now because it will be
1847  renamed and checked at the same time by
1848  value_mappings_compatible_vector_p() */
1849  Pvecteur vlb =
1851  Pvecteur vub = vect_dup(normalized_linear(n1));
1854 
1855  vect_add_elem(&vlb, (Variable) e, val);
1856  vect_add_elem(&vub, (Variable) e, -val);
1857  vect_add_elem(&vub, TCST, VALUE_ONE-val);
1858  clb = contrainte_make(vlb);
1859  cub = contrainte_make(vub);
1860  clb->succ = cub;
1861  tf = make_transformer(NIL,
1863  }
1864 
1865  ifdebug(8) {
1866  pips_debug(8, "result:\n");
1867  dump_transformer(tf);
1868  pips_debug(8, "end\n");
1869  }
1870 
1871  return tf;
1872 }
1873 
1874 /* Assumes that e1 and e2 are integer expressions, i.e. explicit casting
1875  is supposed to be used */
1876 /* Better results might be obtained when e1 is an affine function of e2 or
1877  vice-versa as can occur when convex hulls generate coupling between
1878  variables. See non_linear11.f, 22L1=9L2+40, 1<=L1<=10. The smallest
1879  possible value is -2 and not -20. */
1881  expression e1,
1882  expression e2,
1883  transformer prec,
1884  bool is_internal)
1885 {
1889  transformer t1 = safe_integer_expression_to_transformer(v1, e1, ipre, is_internal);
1891  transformer npre = transformer_safe_apply(t1, ipre);
1892  transformer t2 = safe_integer_expression_to_transformer(v2, e2, npre, is_internal);
1893  //transformer pre = transformer_undefined_p(ipre)? transformer_identity() :
1894  //copy_transformer(ipre);
1896  ipre;
1897 
1898  pips_debug(8, "Begin\n");
1899 
1900  if(transformer_empty_p(t1) || transformer_empty_p(t2)) {
1901  // Some exception occurs during the evaluation of e1 or e2
1902  // For instance, a zero divide
1903  tf = t1;
1904  t1 = transformer_undefined;
1905  }
1906  else if(!transformer_undefined_p(t1) && !transformer_undefined_p(t2)) {
1907  int lb1 = 0;
1908  int ub1 = 0;
1909  int lb2 = 0;
1910  int ub2 = 0;
1911 
1912  /*
1913  * v1 and v2 are temp value,
1914  * so don't have normalize
1915  * so expression_and_precondition_to_integer_interval can't say anything interesting
1916  */
1917  //expression ev1 = entity_to_expression(v1);
1918  //expression ev2 = entity_to_expression(v2);
1919 
1920  /* FI: I had to switch the arguments to satisfy a reasonnable
1921  assert in image_intersection(), but the switch may be
1922  detrimental to memory allocation. */
1923  //t1 = transformer_safe_image_intersection(pre, t1);
1924  //t2 = transformer_safe_image_intersection(pre, t2);
1926  //t2 = transformer_range(transformer_apply(pre, t2));
1928 
1929  // Nelson Lossing: in some cases, these calls are useless and
1930  // return [MIN,MAX] because ev1 and ev2 are built with temporary values
1931  // In his case, it works if ev1 and ev2 are replaced by e1 and e2
1932  //expression_and_precondition_to_integer_interval(ev1, t1, &lb1, &ub1);
1933  //expression_and_precondition_to_integer_interval(ev2, t2, &lb2, &ub2);
1934  // FI-> Nelson: there may be a problem, but your are reanalyzing
1935  //e1 and e2, which has just been performed above; and you fail when side
1936  // effects occur (multiply07.c)
1937  //integer_expression_and_precondition_to_integer_interval(e1, p1, &lb1, &ub1);
1938  //integer_expression_and_precondition_to_integer_interval(e2, p2, &lb2, &ub2);
1941  //free_expression(ev1);
1942  //free_expression(ev2);
1943 
1944  if(lb1==ub1) {
1945  /* The numerical value of expression e1 is known: v = lb1*v2 */
1946  Pvecteur veq = vect_new((Variable) v, VALUE_MONE);
1947 
1948  vect_add_elem(&veq, (Variable) v2, (Value) lb1);
1949  tf = transformer_combine(t1, t2);
1950  transformer_equality_add(tf, veq);
1951  t1 = transformer_undefined;
1952  //free_transformer(t1);
1953  }
1954  else if(lb2==ub2) {
1955  /* The numerical value of expression e2 is known: v = lb2*v1 */
1956  Pvecteur veq = vect_new((Variable) v, VALUE_MONE);
1957 
1958  vect_add_elem(&veq, (Variable) v1, (Value) lb2);
1959  tf = transformer_combine(t1, t2);
1960  tf = transformer_equality_add(tf, veq);
1961  t1 = transformer_undefined;
1962  //free_transformer(t2);
1963  }
1964  else if(ub1<=0) { // e1 is negative
1965  if(ub2<=0) { // e2 is negative
1966  // v >= v1 * ub2, v >= ub1 * v2
1967  // v <= v1 * lb2, v <= lb1 * v2 (if lb1 and lb2 exist)
1968  tf = transformer_intersection(t1,t2); // FI: not good if side effects!
1969  tf = transformer_normalize(tf, 2);
1970  tf = transformer_add_inequality_with_linear_term(tf,v,v1,ub2,false);
1971  tf = transformer_add_inequality_with_linear_term(tf,v,v2,ub1,false);
1972  if(lb2>INT_MIN)
1973  tf = transformer_add_inequality_with_linear_term(tf,v,v1,lb2,true);
1974  if(lb1>INT_MIN)
1975  tf = transformer_add_inequality_with_linear_term(tf,v,v2,lb1,true);
1976  }
1977  else if(lb2>=0) { // e2 is positive
1978  // v <= v1 * lb2, v <= ub1 * v2
1979  // v >= v1 * ub2, v >= lb1 * v2 (if lb1 and ub2 exist)
1980  tf = transformer_intersection(t1,t2); // FI: not good if side effects!
1981  tf = transformer_normalize(tf, 2);
1982  tf = transformer_add_inequality_with_linear_term(tf,v,v1,lb2,true);
1983  tf = transformer_add_inequality_with_linear_term(tf,v,v2,ub1,true);
1984  if(ub2<INT_MAX)
1985  tf = transformer_add_inequality_with_linear_term(tf,v,v1,ub2,false);
1986  if(lb1>INT_MIN)
1987  tf = transformer_add_inequality_with_linear_term(tf,v,v2,lb1,false);
1988  }
1989  else { // if lb2 and ub2 are known and their signs are different
1990  if(lb2>INT_MIN && ub2<INT_MAX) {
1991  // v1 * ub2 <= v <= v1 * lb2
1992  tf = transformer_intersection(t1,t2); // FI: not good if side effects!
1993  tf = transformer_normalize(tf, 2);
1994  tf = transformer_add_inequality_with_linear_term(tf,v,v1,ub2,false);
1995  tf = transformer_add_inequality_with_linear_term(tf,v,v1,lb2,true);
1996  ;
1997  }
1998  else {
1999  tf = transformer_identity();
2000  }
2001 
2002  }
2003  }
2004  else if(lb1>=0) {
2005  if(lb2>=0) {
2006  // v >= lb1 * v2, v >= v1 * lb2
2007  // v <= ub1 * v2, v <= v1 * ub2 (if ub1 and ub2 exist)
2008  tf = transformer_intersection(t1,t2); // FI: not good if side effects!
2009  tf = transformer_normalize(tf, 2);
2010  tf = transformer_add_inequality_with_linear_term(tf,v,v2,lb1,false);
2011  tf = transformer_add_inequality_with_linear_term(tf,v,v1,lb2,false);
2012  if(ub1<INT_MAX)
2013  tf = transformer_add_inequality_with_linear_term(tf,v,v2,ub1,true);
2014  if(ub2<INT_MAX)
2015  tf = transformer_add_inequality_with_linear_term(tf,v,v1,ub2,true);
2016  }
2017  else if(ub2<=0) {
2018  // v <= v1 * ub2, v <= lb1 * v2
2019  // v >= v1 * lb2, v >= ub1 * v2 (if ub1 and lb2 exist)
2020  tf = transformer_intersection(t1,t2); // FI: not good if side effects!
2021  tf = transformer_normalize(tf, 2);
2022  tf = transformer_add_inequality_with_linear_term(tf,v,v1,ub2,true);
2023  tf = transformer_add_inequality_with_linear_term(tf,v,v2,lb1,true);
2024  if(lb2>INT_MIN)
2025  tf = transformer_add_inequality_with_linear_term(tf,v,v1,lb2,false);
2026  if(ub1>INT_MAX)
2027  tf = transformer_add_inequality_with_linear_term(tf,v,v2,ub1,false);
2028  ;
2029  }
2030  else {
2031  if(lb2>INT_MIN && ub2<INT_MAX) { // FI: separated test needed
2032  // v1 * lb2 <= v <= v1 * ub2
2033  tf = transformer_intersection(t1,t2); // FI: not good if side effects!
2034  tf = transformer_normalize(tf, 2);
2035  tf = transformer_add_inequality_with_linear_term(tf,v,v1,lb2,false);
2036  tf = transformer_add_inequality_with_linear_term(tf,v,v1,ub2,true);
2037  }
2038  else {
2039  tf = transformer_identity();
2040  }
2041  }
2042  }
2043  else {
2044  /* FI: This should now be obsolete... but it is not when the
2045  signs are unknown */
2046 
2047  /* Do we have range information? */
2048  long long p1 = ((long long) lb1 )*((long long) lb2 );
2049  long long p2 = ((long long) lb1 )*((long long) ub2 );
2050  long long p3 = ((long long) ub1 )*((long long) lb2 );
2051  long long p4 = ((long long) ub1 )*((long long) ub2 );
2052  long long lb = (p2<p1)? p2 : p1;
2053  long long ub = (p2>p1)? p2 : p1;
2054 
2055  lb = (p3<lb)? p3 : lb;
2056  lb = (p4<lb)? p4 : lb;
2057 
2058  ub = (p3>ub)? p3 : ub;
2059  ub = (p4>ub)? p4 : ub;
2060 
2061  //free_transformer(t1);
2062  //free_transformer(t2);
2063 
2064  if(lb > INT_MIN || ub < INT_MAX)
2065  tf = transformer_identity();
2066 
2067  if(lb > INT_MIN) {
2068  Pvecteur vineql = vect_new((Variable) v, VALUE_MONE);
2069 
2070  vect_add_elem(&vineql, TCST, lb);
2072  }
2073  if(ub < INT_MAX) {
2074  Pvecteur vinequ = vect_new((Variable) v, VALUE_ONE);
2075 
2076  vect_add_elem(&vinequ, TCST, -ub);
2077  tf = transformer_inequality_add(tf, vinequ);
2078  }
2079  }
2080  }
2081  else if(!transformer_undefined_p(t1)) {
2082  // free_transformer(t1);
2083  }
2084  else if(!transformer_undefined_p(t2)) {
2085  //free_transformer(t2);
2086  //t2 = transformer_undefined;
2087  }
2088 
2089  free_transformer(pre);
2090 
2091  /* let's try to exploit some properties of squaring, but the
2092  detection is poor. For instance 2*i*i won't be identified as a
2093  square. */
2094  if(transformer_undefined_p(tf)) {
2095  /* let's assume no impact from side effects */
2096  if(expression_equal_p(e1, e2)) {
2097  // FI: we could do a much better job here
2098  // a different function such as integer_square_to_transformer()
2099  // should be called to also generate the first terms
2100  // v>=t, v>=-t, v>=3t-2, v>=-3t-2
2101  // This terms are useful when t is connected because e1 is
2102  // affine and when the programmer plays on the behavior of
2103  // square around 0
2104  // See cavern01.c
2105 
2106  /* v is greater than v1 and -v1. This makes v>=0 redundant */
2107  if(!transformer_undefined_p(t1)) {
2108  tf = transformer_add_inequality(t1, v1, v, false);
2110  v1, VALUE_MONE, VALUE_ZERO,
2111  false);
2112  /* Memory leak with tf... */
2113  tf = transformer_intersection(tf, t1);
2114  }
2115  else {
2116  /* The result is always positive: v>=0 */
2117  Pvecteur vineq = vect_new((Variable) v, VALUE_MONE);
2118  tf = transformer_identity();
2119  tf = transformer_inequality_add(tf, vineq);
2120  }
2121  }
2122  else if(expression_opposite_p(e1, e2)) {
2123  /* v is less than v1 and -v1. This makes v<=0 redundant */
2124  if(!transformer_undefined_p(t1)) {
2125  tf = transformer_add_inequality(t1, v, v1, false);
2127  v1, VALUE_MONE, VALUE_ZERO,
2128  true);
2129  /* Memory leak with tf... */
2130  tf = transformer_intersection(tf, t1);
2131  }
2132  else {
2133  /* The result is always negative: v<=0 */
2134  Pvecteur vineq = vect_new((Variable) v, VALUE_ONE);
2135  tf = transformer_identity();
2136  tf = transformer_inequality_add(tf, vineq);
2137  }
2138  }
2139  }
2140  else {
2141  if(expression_equal_p(e1, e2)) {
2142  /* The result is always positive: v>=0 */
2143  Pvecteur vineq = vect_new((Variable) v, VALUE_MONE);
2144  tf = transformer_inequality_add(tf, vineq);
2145  }
2146  else if(expression_opposite_p(e1, e2)) {
2147  /* The result is always negative: v<=0 */
2148  Pvecteur vineq = vect_new((Variable) v, VALUE_ONE);
2149  tf = transformer_inequality_add(tf, vineq);
2150  }
2151  }
2152 
2153  if(!transformer_undefined_p(t1)) {
2154  free_transformer(t1);
2155  }
2156  if(!transformer_undefined_p(t2)) {
2157  free_transformer(t2);
2158  }
2159 
2160  pips_debug(8, "End with tf=%p\n", tf);
2161  ifdebug(8) (void) dump_transformer(tf);
2162 
2163  return tf;
2164 }
2165 
2166 /* cut-and-pasted and adapted from multiply_to_transformer(); */
2167 // only take 1 arg as expression which will multiply by the sizeof
2168 // it's a version simplify of multiply_to_transformer because we know that sizeof>0.
2170  expression e1,
2171  transformer prec,
2172  bool is_internal)
2173 {
2174  type tv = entity_type(v);
2175  type t = type_undefined;
2176  if (type_variable_p(tv)) {
2178  if (basic_pointer_p(b))
2179  t = basic_pointer(b);
2180  }
2181  if (type_undefined_p(t)) {
2182  return transformer_empty();
2183  }
2184 
2185 
2186  // create an entity for sizeof(type)
2187  add_sizeof_value(t);
2188  // get the sizeof entity
2189  entity val2 = type_to_sizeof_value(t);
2190  // convert to expression for transformer
2191  expression e2 = entity_to_expression(val2);
2192 
2196  transformer t1 = safe_integer_expression_to_transformer(v1, e1, ipre, is_internal);
2198  transformer npre = transformer_safe_apply(t1, ipre);
2199  transformer t2 = safe_integer_expression_to_transformer(v2, e2, npre, is_internal);
2201  ipre;
2202 
2203  pips_debug(8, "Begin\n");
2204 
2206  int lb1 = 0;
2207  int ub1 = 0;
2208  //e2 sizeof then positive
2209 
2210  /* FI: I had to switch the arguments to satisfy a reasonnable
2211  assert in image_intersection(), but the switch may be
2212  detrimental to memory allocation. */
2213  //t1 = transformer_safe_image_intersection(pre, t1);
2214  t1 = transformer_normalize(t1, 2);
2215  t1 = transformer_range(transformer_apply(pre, t1));
2216 
2218 
2219  if(lb1==ub1) {
2220  /* The numerical value of expression e1 is known: v = lb1*v2 */
2221  Pvecteur veq = vect_new((Variable) v, VALUE_MONE);
2222 
2223  vect_add_elem(&veq, (Variable) v2, (Value) lb1);
2224  transformer_equality_add(t2, veq);
2225  tf = t2;
2226  free_transformer(t1);
2227  }
2228  else if(ub1<=0) { // e1 is negative
2229  // e2 is positive
2230  // v <= v1 * lb2, v <= ub1 * v2
2231  // v >= v1 * ub2, v >= lb1 * v2 (if lb1 and ub2 exist)
2232  tf = transformer_intersection(t1,t2); // FI: not good if side effects!
2233  tf = transformer_normalize(tf, 2);
2234  tf = transformer_add_inequality_with_linear_term(tf,v,v2,ub1,true);
2235  if(lb1>INT_MIN)
2236  tf = transformer_add_inequality_with_linear_term(tf,v,v2,lb1,false);
2237  }
2238  else if(lb1>=0) {
2239  // v >= lb1 * v2, v >= v1 * lb2
2240  // v <= ub1 * v2, v <= v1 * ub2 (if ub1 and ub2 exist)
2241  tf = transformer_intersection(t1,t2); // FI: not good if side effects!
2242  tf = transformer_normalize(tf, 2);
2243  tf = transformer_add_inequality_with_linear_term(tf,v,v2,lb1,false);
2244  if(ub1<INT_MAX)
2245  tf = transformer_add_inequality_with_linear_term(tf,v,v2,ub1,true);
2246  }
2247  else { // FI: This should now be obsolete...
2248  if(lb1>INT_MIN && ub1<INT_MAX) { // FI: separated test needed
2249  // v1 * lb2 <= v <= v1 * ub2
2250  tf = transformer_intersection(t1,t2); // FI: not good if side effects!
2251  tf = transformer_normalize(tf, 2);
2252  tf = transformer_add_inequality_with_linear_term(tf,v,v2,lb1,false);
2253  tf = transformer_add_inequality_with_linear_term(tf,v,v2,ub1,true);
2254  }
2255  else {
2256  long long lb = lb1;
2257  long long ub = ub1;
2258 
2259  free_transformer(t1);
2260  free_transformer(t2);
2261 
2262  if(lb > INT_MIN || ub < INT_MAX)
2263  tf = transformer_identity();
2264 
2265  if(lb > INT_MIN) {
2266  Pvecteur vineql = vect_new((Variable) v, VALUE_MONE);
2267 
2268  vect_add_elem(&vineql, TCST, lb);
2270  }
2271  if(ub < INT_MAX) {
2272  Pvecteur vinequ = vect_new((Variable) v, VALUE_ONE);
2273 
2274  vect_add_elem(&vinequ, TCST, -ub);
2275  tf = transformer_inequality_add(tf, vinequ);
2276  }
2277  }
2278  }
2279  }
2280  else if(!transformer_undefined_p(t1)) {
2281  free_transformer(t1);
2282  }
2283  else if(!transformer_undefined_p(t2)) {
2284  free_transformer(t2);
2285  }
2286 
2287  free_transformer(pre);
2288  free_expression(e2);
2289 
2290  pips_debug(8, "End with tf=%p\n", tf);
2291  ifdebug(8) (void) dump_transformer(tf);
2292 
2293  return tf;
2294 }
2295 ␌
2296 /* Assumes that e1 and e2 are integer expressions, i.e. explicit casting
2297  * is supposed to be used.
2298  *
2299  * This piece of code has been copied and pasted from
2300  * integer_multiply_to_transformer(). Common issues like evaluating
2301  * the intervals for the values of the arguments should be factored
2302  * out. */
2304  expression e1,
2305  expression e2,
2306  transformer prec,
2307  bool is_internal)
2308 {
2310  // FI: ultimate_type should be called? Or int assumed?
2312  transformer ipre = transformer_undefined_p(prec)?
2314  transformer t1 = safe_integer_expression_to_transformer(v1, e1, ipre, is_internal);
2316  transformer npre = transformer_safe_apply(t1, ipre);
2317  transformer t2 = safe_integer_expression_to_transformer(v2, e2, npre, is_internal);
2318  //transformer pre = transformer_undefined_p(ipre)? transformer_identity() :
2319  // copy_transformer(ipre);
2320  transformer pre = ipre;
2321 
2322  pips_debug(8, "Begin\n");
2323 
2325  intptr_t lb1 = 0;
2326  intptr_t ub1 = 0;
2327  intptr_t lb2 = 0;
2328  intptr_t ub2 = 0;
2329 
2330  /* FI: I had to switch the arguments to satisfy a reasonnable
2331  assert in image_intersection(), but the switch may be
2332  detrimental to memory allocation. */
2333  //t1 = transformer_safe_image_intersection(pre, t1);
2334  //t2 = transformer_safe_image_intersection(pre, t2);
2335  t1 = transformer_range(transformer_apply(pre, t1));
2336  t2 = transformer_range(transformer_apply(pre, t2));
2337 
2338  (void) precondition_minmax_of_value(v1, t1, &lb1, &ub1);
2339  (void) precondition_minmax_of_value(v2, t2, &lb2, &ub2);
2340 
2341  if(lb2==ub2) {
2342  /* The numerical value of expression e2 is known: v = v1*2^lb2 */
2343  Pvecteur veq = vect_new((Variable) v, VALUE_MONE);
2344 
2345  if(lb2>=0) {
2346  vect_add_elem(&veq, (Variable) v1,
2347  value_lshift((Value) 1, (Value) lb2));
2348  }
2349  else /* lb2<0 */ {
2350  // FI: Should look at the norm; seems to return 0 with gdb
2351  ;
2352  }
2353 
2354  tf = transformer_equality_add(t1, veq);
2355  free_transformer(t2);
2356  }
2357  else if(0<lb2 && ub2<INT_MAX) {
2358  /* The value of v belongs to a bounded interval */
2359  if(0<=lb1) {
2360  // v1 is positive: v1*2^lb2 <= v <= v1*2^ub2
2361  Pvecteur veq1 = vect_new((Variable) v, VALUE_MONE);
2362  Pvecteur veq2 = vect_new((Variable) v, VALUE_ONE);
2363  vect_add_elem(&veq1, (Variable) v1,
2364  value_lshift((Value) 1, (Value) lb2));
2365  vect_add_elem(&veq2, (Variable) v1,
2366  -value_lshift((Value) 1, (Value) ub2));
2367  tf = transformer_inequality_add(t1, veq1);
2368  tf = transformer_inequality_add(t1, veq2);
2369  free_transformer(t2);
2370  }
2371  else if(ub1<=0) {
2372  // v1 is negative: v1*2^ub2 <= v <= v1*2^lb2
2373  Pvecteur veq1 = vect_new((Variable) v, VALUE_MONE);
2374  Pvecteur veq2 = vect_new((Variable) v, VALUE_ONE);
2375  vect_add_elem(&veq1, (Variable) v1,
2376  value_lshift((Value) 1, (Value) ub2));
2377  vect_add_elem(&veq2, (Variable) v1,
2378  -value_lshift((Value) 1, (Value) lb2));
2379  tf = transformer_inequality_add(t1, veq1);
2380  tf = transformer_inequality_add(t1, veq2);
2381  free_transformer(t2);
2382  }
2383  else {
2384  // No information is available because the sign of v1 is
2385  // unknown
2386  ;
2387  }
2388  }
2389  else {
2390  // Let's hope that the sign of v2 is known as well as the sign
2391  // of v1. It does not matter if v1 is known exactly or not
2392  // a new transformer must be built
2393  //free_transformer(t1);
2394  free_transformer(t2);
2395  //transformer tf = transformer_identity();
2396 
2397  if(lb2>=0 && lb1>=1) {
2398  // The value of v is greater than the value of v1 multiplied
2399  // by 2
2400  tf = transformer_add_inequality_with_affine_term(t1, v, v1, 2, 0, false);
2401  }
2402  else if(lb2>=0 && lb1==0) {
2403  // The value of v is 0
2404  tf = transformer_add_inequality(t1, v1, v, false);
2405  //tf = transformer_add_equality_with_integer_constant(tf, v, 0);
2406  }
2407  else if(lb2>0 && ub1<0) {
2408  // The value of v is lesser than the value of v1
2409  tf = transformer_add_inequality(t1, v, v1, true);
2410  }
2411  else if(lb2>0 && ub1==0) {
2412  // The value of v is lesser than the value of v1
2413  tf = transformer_add_inequality(t1, v, v1, false);
2414  }
2415  else if(ub2<0) {
2416  // The value of v is zero
2417  free_transformer(t1);
2418  tf = transformer_identity();
2420  }
2421  else // nothing is know about v2: the sign of v1 is preserved
2422  // To be checked in C standard...
2423  if(0<=lb1)
2425  else if(ub1<=0)
2427  }
2428  }
2429  else if(!transformer_undefined_p(t1)) {
2430  free_transformer(t1);
2431  }
2432  else if(!transformer_undefined_p(t2)) {
2433  free_transformer(t2);
2434  }
2435 
2436  free_transformer(pre);
2437 
2438  pips_debug(8, "End with tf=%p\n", tf);
2439  ifdebug(8) (void) dump_transformer(tf);
2440 
2441  return tf;
2442 }
2443 ␌
2445  expression arg1,
2446  expression arg2,
2447  transformer prec,
2448  bool is_internal)
2449 {
2451  normalized n1 = NORMALIZE_EXPRESSION(arg1);
2452  normalized n2 = NORMALIZE_EXPRESSION(arg2);
2455 
2456  pips_debug(8, "begin\n");
2457 
2458  /* Should be rewritten using expression_to_transformer and expression
2459  evaluation as in integer_multiply_to_transformer */
2460  /* pips_assert("Precondition is unused", transformer_undefined_p(pre)); */
2461  //pips_assert("Shut up the compiler", pre==pre);
2462  pips_assert("Shut up the compiler", is_internal==is_internal);
2463 
2464  /* Is arg1 bounded? constant? */
2465  bool arg1_is_constant_p = false;
2466  //bool arg1_is_bounded_p = false;
2467  intptr_t lb1, ub1;
2468  if(precondition_minmax_of_expression(arg1, pre, &lb1, &ub1)) {
2469  if(lb1==ub1) {
2470  arg1_is_constant_p = true;
2471  }
2472  }
2473  /* Is arg2 bounded? constant? */
2474  bool arg2_is_constant_p = false;
2475  //bool arg2_is_bounded_p = false;
2476  intptr_t lb2, ub2;
2477  if(precondition_minmax_of_expression(arg2, pre, &lb2, &ub2)) {
2478  if(lb2==ub2) {
2479  arg2_is_constant_p = true;
2480  }
2481  }
2482 
2483  if(arg1_is_constant_p && arg2_is_constant_p) {
2484  int v = (int) exponentiate((Value) lb1, (Value) lb2);
2485  tf = transformer_identity();
2487  }
2488  else if(arg2_is_constant_p && normalized_linear_p(n1)) {
2489  //int d = signed_integer_constant_expression_value(arg2);
2490  int d = (int) lb2;
2491 
2492  if(d%2==0) {
2493 
2494  if(d==0) {
2495  /* 1 is assigned unless arg1 equals 0... which is neglected */
2496  Pvecteur v = vect_new((Variable) e, VALUE_ONE);
2497 
2499  tf = make_transformer(NIL,
2502  }
2503  else if(d>0) {
2504  /* Does not work because unary minus is not seen as part of a constant */
2505  /* The expression value must be greater or equal to arg2 and positive */
2506  /* must be duplicated right now because it will be
2507  renamed and checked at the same time by
2508  value_mappings_compatible_vector_p() */
2509  Pvecteur vlb1 = vect_dup(normalized_linear(n1));
2513 
2514  vect_add_elem(&vlb1, (Variable) e, VALUE_MONE);
2515  vect_add_elem(&vlb2, (Variable) e, VALUE_MONE);
2516  clb1 = contrainte_make(vlb1);
2517  clb2 = contrainte_make(vlb2);
2518  clb1->succ = clb2;
2519  tf = make_transformer(NIL,
2521  }
2522  else {
2523  /* d is negative and even */
2524  Pvecteur vub = vect_new((Variable) e, VALUE_ONE);
2525  Pvecteur vlb = vect_new((Variable) e, VALUE_MONE);
2528 
2529  vect_add_elem(&vub, TCST, VALUE_MONE);
2530  clb = contrainte_make(vlb);
2531  cub = contrainte_make(vub);
2532  clb->succ = cub;
2533  tf = make_transformer(NIL,
2535  }
2536  }
2537  else if(d<0) {
2538  /* d is negative, arg1 cannot be 0, expression value is -1, 0
2539  or 1 */
2540  Pvecteur vub = vect_new((Variable) e, VALUE_MONE);
2541  Pvecteur vlb = vect_new((Variable) e, VALUE_ONE);
2544 
2545  vect_add_elem(&vub, TCST, VALUE_MONE);
2546  vect_add_elem(&vlb, TCST, VALUE_MONE);
2547  clb = contrainte_make(vlb);
2548  cub = contrainte_make(vub);
2549  clb->succ = cub;
2550  tf = make_transformer(NIL,
2552  }
2553  else if(d==1) {
2555 
2556  vect_add_elem(&v, (Variable) e, VALUE_MONE);
2557  tf = make_transformer(NIL,
2560  }
2561  }
2562  else if(arg1_is_constant_p) {
2563  //int d = signed_integer_constant_expression_value(arg1);
2564  int d = (int) lb1;
2565 
2566  if(d==0||d==1) {
2567  /* 0 or 1 is assigned unless arg2 equals 0... which is neglected */
2568  Pvecteur v = vect_new((Variable) e, VALUE_ONE);
2569 
2570  vect_add_elem(&v, TCST, int_to_value(-d));
2571  tf = make_transformer(NIL,
2574  }
2575  else if(d > 1) { // e>=0, always
2576 
2577  tf = transformer_identity();
2578 
2579  /* e >= d^lb2 */
2580  if(lb2>=1) {
2581  Value elb2 = exponentiate((Value) d, (Value) lb2);
2582  tf =
2584  (Variable) e,
2585  (int) elb2,
2586  false);
2587  }
2588 
2589  /* e <= d^lb2 */
2590  if(ub2<INT_MAX) {
2591  // FI: let's hope no overflow is generated...
2592  Value eub2 = exponentiate((Value) d, (Value) ub2);
2593  tf =
2595  (Variable) e,
2596  (int) eub2,
2597  true);
2598  }
2599 
2600 
2601  /* the assigned value is positive */
2602  Pvecteur v1 = vect_new((Variable) e, VALUE_MONE);
2603  //Pcontrainte c1 = contrainte_make(v1);
2604  tf = transformer_inequality_add(tf, v1);
2605 
2606  if(normalized_linear_p(n2)) {
2608  //Pcontrainte c2 = CONTRAINTE_UNDEFINED;
2610  //Pcontrainte c3 = CONTRAINTE_UNDEFINED;
2611 
2612  vect_add_elem(&v2, TCST, VALUE_ONE);
2613  vect_add_elem(&v2, (Variable) e, VALUE_MONE);
2614  tf = transformer_inequality_add(tf, v2);
2615  // c2 = contrainte_make(v2);
2616  //contrainte_succ(c1) = c2;
2617  vect_add_elem(&v3, (Variable) e, VALUE_MONE);
2618  //c3 = contrainte_make(v3);
2619  //contrainte_succ(c2) = c3;
2620  tf = transformer_inequality_add(tf, v3);
2621  }
2622 
2623  //tf = make_transformer(NIL,
2624  // make_predicate(sc_make(CONTRAINTE_UNDEFINED, c1)));
2625 
2626  }
2627  else if(d == -1) {
2628  /* The assigned value is 1 or -1 */
2629  Pvecteur vub = vect_new((Variable) e, VALUE_MONE);
2630  Pvecteur vlb = vect_new((Variable) e, VALUE_ONE);
2633 
2634  vect_add_elem(&vub, TCST, VALUE_MONE);
2635  vect_add_elem(&vlb, TCST, VALUE_MONE);
2636  clb = contrainte_make(vlb);
2637  cub = contrainte_make(vub);
2638  clb->succ = cub;
2639  tf = make_transformer(NIL,
2641  }
2642  }
2643 
2644  free_transformer(pre);
2645 
2646  ifdebug(8) {
2647  pips_debug(8, "result:\n");
2648  dump_transformer(tf);
2649  pips_debug(8, "end\n");
2650  }
2651 
2652  return tf;
2653 }
2654 ␌
2655 static transformer integer_minmax_to_transformer(entity v, /*value for minmax*/
2656  list args,
2657  transformer pre,
2658  bool is_min,
2659  bool is_internal)
2660 {
2662  list cexpr;
2663  intptr_t bound = is_min? LONG_MAX : LONG_MIN;
2664 
2665  pips_debug(8, "begin for %s %s\n",
2666  is_min? "minimum" : "maximum",
2667  is_internal? "intraprocedural" : "interprocedural");
2668 
2669  for(cexpr = args; !ENDP(cexpr); POP(cexpr)) {
2670  expression arg = EXPRESSION(CAR(cexpr));
2671  intptr_t lb, ub;
2672  if(precondition_minmax_of_expression(arg, pre, &lb, &ub)) {
2673  // FI: useless precision loss, anticipating
2674  // transformer_add_inequality_with+integer_constraint()
2675  bound = is_min? (MIN(bound, lb)) : (MAX(bound, ub));
2676  }
2677  else {
2678  bound = is_min? LONG_MIN : LONG_MAX;
2679  }
2682  is_internal);
2683  Pvecteur vineq = vect_new((Variable) tv, (Value) VALUE_ONE);
2684 
2685  vect_add_elem(&vineq, (Variable) v, VALUE_MONE);
2686 
2687  if(is_min) {
2688  vineq = vect_multiply(vineq, VALUE_MONE);
2689  }
2690 
2691  tf = transformer_inequality_add(tf, vineq);
2693  free_transformer(etf);
2694  }
2695 
2696  if(bound!=LONG_MIN && bound!=LONG_MAX) { // FI: this test does not
2697  // seem to work as expected...
2698  int b = (int) bound;
2699  if((intptr_t) b == bound) { // FI: for safety...
2700  //tf = transformer_add_inequality_with_integer_constant(tf, v, bound, is_min);
2702  }
2703  }
2704 
2705  // FI: not strong enough to remove stupid redundancy. See
2706  // Semantics/minmax3
2707  // I do not dare add a stronger normalization because it could
2708  // impact the execution time too much...
2709  //tf = transformer_normalize(tf, 2);
2710 
2711  ifdebug(8) {
2712  pips_debug(8, "result:\n");
2713  dump_transformer(tf);
2714  pips_debug(8, "end\n");
2715  }
2716 
2717  return tf;
2718 }
2719 
2721  list args,
2722  transformer pre,
2723  bool is_internal)
2724 {
2725  return integer_minmax_to_transformer(e, args, pre, true, is_internal);
2726 }
2727 
2729  list args,
2730  transformer pre,
2731  bool is_internal)
2732 {
2733  return integer_minmax_to_transformer(e, args, pre, false, is_internal);
2734 }
2735 ␌
2736 /* Returns an undefined transformer in case of failure */
2737 transformer assign_operation_to_transformer(entity val, // assumed to be a value, not to have values
2738  expression lhs,
2739  expression rhs,
2740  transformer pre)
2741 {
2743 
2744  pips_debug(8,"begin\n");
2745 
2746  if(expression_reference_p(lhs)) {
2748 
2749  if(entity_has_values_p(e) /* && integer_scalar_entity_p(e) */) {
2750  entity ev = entity_to_new_value(e);
2751  //transformer teq = simple_equality_to_transformer(val, ev, true);
2752  tf = assigned_expression_to_transformer(ev, rhs, pre);
2753  if(!transformer_undefined_p(tf))
2754  tf = transformer_add_equality(tf, val, ev);
2755  //tf = transformer_combine(tf, teq);
2756  //free_transformer(teq);
2757  }
2758  }
2759 
2760  pips_debug(6,"return tf=%lx\n", (unsigned long)tf);
2761  ifdebug(6) (void) dump_transformer(tf);
2762  pips_debug(8,"end\n");
2763  return tf;
2764 }
2765 ␌
2766 /* This function is redundant with generic_unary_operation_to_transformer()
2767  * except for its use of parameter is_pointer
2768  */
2769 
2771  entity op,
2772  expression e1,
2773  transformer pre,
2774  bool is_internal,
2775  bool is_pointer)
2776 {
2777  pips_debug(8, "begin \n");
2779 
2780  if (!pt_to_list_undefined_p()) {
2781  // FI: may have to be adapted to implement ANALYZE_CONSTANT_PATHS
2782  //statement curstat = get_current_statement_from_statement_global_stack();
2783  //points_to_graph ptg = get_points_to_graph_from_statement(curstat);
2784 
2786  // compute the assignment for each cell pointed with the convex hull
2787  FOREACH(CELL, cp, l) {
2789  entity rhs = reference_variable(rrhs);
2790 
2791  if (!is_pointer && entity_null_locations_p(rhs)) {
2792  if (gen_length(l) == 1) {
2793  tf = transformer_empty();
2794  pips_user_error("The pointer %s points to NULL\n", expression_to_string(e1));
2795  }
2796  else {
2797  semantics_user_warning("The pointer %s can points to NULL\n", expression_to_string(e1));
2798  }
2799  } else if (entity_typed_nowhere_locations_p(rhs)) {
2800  if (gen_length(l) == 1) {
2801  tf = transformer_empty();
2802  pips_user_error("The pointer %s points to undefined/indeterminate (%s)\n", expression_to_string(e1), reference_to_string(rrhs));
2803  }
2804  else {
2805  semantics_user_warning("The pointer %s can points to undefined/indeterminate (%s)\n", expression_to_string(e1), reference_to_string(rrhs));
2806  }
2807  }
2808  else {
2809  // check if rrhs is a constant path and can be analyze or not
2810  // (not really exact, see detail in analyzed_reference_p)
2811  if (analyzed_reference_p(rrhs)) {
2812  transformer rt = generic_reference_to_transformer(e, rrhs, pre, is_internal);
2813  // NL : It must have be a better way to do that but I don't know how
2814  if (transformer_undefined_p(tf))
2815  tf = rt;
2816  else {
2817  tf = transformer_convex_hull(tf, rt);
2818  free_transformer(rt);
2819  }
2820  }
2821  }
2822  }
2823  }
2824 
2825  if (transformer_undefined_p(tf)) {
2827  if(test_warning_counters()) {
2828  extern bool active_phase_p(const char *);
2829  if(active_phase_p("TRANSFORMERS_INTER_FULL_WITH_POINTS_TO")) {
2830  if(get_bool_property("SEMANTICS_ANALYZE_CONSTANT_PATH"))
2831  ;
2832  else
2833  semantics_user_warning("Set property SEMANTICS_ANALYZE_CONSTANT_PATH TRUE."
2834  " It might generate more accurate transformers.\n");
2835  }
2836  else {
2837  if(get_bool_property("SEMANTICS_ANALYZE_CONSTANT_PATH"))
2838  semantics_user_warning("Activate TRANSFORMERS_INTER_FULL_WITH_POINTS_TO."
2839  " It might generate more accurate transformers.\n");
2840  else
2841  semantics_user_warning("Activate TRANSFORMERS_INTER_FULL_WITH_POINTS_TO and "
2842  "setproperty SEMANTICS_ANALYZE_CONSTANT_PATH TRUE."
2843  " It might generate more accurate transformers.\n");
2844  }
2845  }
2846  }
2847  }
2848 
2849  ifdebug (8) dump_transformer(tf);
2850  pips_debug(8, "end \n");
2851  return tf;
2852 }
2853 
2854 /* FI: this function is no longer useful (11 August 2013) */
2855 static transformer
2857  entity e __attribute__ ((unused)),
2858  entity f __attribute__ ((unused)),
2859  transformer pre __attribute__ ((unused)),
2860  bool is_internal __attribute__ ((unused)))
2861 {
2862  // eg : getchar and sizeof are nullary_operation
2864  /* rand() returns an integer between 0 and RAND_MAX. See
2865  Semantics/rand01.c
2866 
2867  How do you make sure that RAND_MAX is the same for the analyzed
2868  code and for the analyzer?
2869  */
2870  /* NL already parse by the function which call him (integer_call_expression_to_transformer)
2871  if (ENTITY_RAND_P(f)) {
2872  tf = transformer_add_inequality_with_integer_constraint(transformer_identity(),
2873  e, 0, true);
2874  }
2875  */
2876 
2877  return tf;
2878 }
2879 
2881  entity op,
2882  expression e1,
2883  transformer pre,
2884  bool is_internal)
2885 {
2887 
2888  tf = generic_unary_operation_to_transformer(e, op, e1, pre, is_internal);
2889 
2890  if(transformer_undefined_p(tf)) {
2891  if(ENTITY_IABS_P(op)
2892  || ENTITY_C_ABS_P(op) || ENTITY_LABS_P(op) || ENTITY_LLABS_P(op)) {
2893  tf = iabs_to_transformer(e, e1, pre, is_internal);
2894  }
2895  }
2896 
2897  // if(transformer_undefined_p(tf)) {
2898  // tf = generic_unary_operation_to_transformer(e, op, e1, pre, is_internal);
2899  //}
2900 
2901  return tf;
2902 }
2903 
2904 struct interval_product {int lb1; int ub1; int lb2; int ub2; bool positive_p;};
2905 
2906 /* Auxiliary function for non-affine operators such as divide,
2907  * multiply, modulo...
2908  *
2909  * Returns an equivalent set of interval products whose bounds are
2910  * always positive plus some information about the global sign for the
2911  * result. For instance, [-3,4] x [-5,6] is broken down into four products:
2912  * - [1,3] x [1,5] positive
2913  * - [1,3] x [0,6] negative
2914  * - [0,4] x [1,5] negative
2915  * - [0,4] x [0,6] positive
2916  *
2917  * For division, 0 is excluded and the positive intervals start at 1
2918  * instead of 0.
2919  *
2920  * Intervals may be empty: [1,0].
2921  */
2922 
2923 /* DEAD CODE
2924 static void break_intervals_into_positive_intervals(int lb1, int ub1, int lb2, int ub2, struct interval_product cases[4], int * pncase, bool exclude_zero_p)
2925 {
2926  // We need a pair of macros to process -MAX_INT and -MIN_INT,
2927  // MINUS_UPPER_BOUND and MINUS_LOWER_BOUND, because of the disymetry
2928  // in the encoding of integers
2929  //
2930 
2931  int nlb = exclude_zero_p? 1 : 0;
2932  if(false) {
2933  *pncase = 0;
2934  if(lb1>=0) {
2935  // The first interval is positive
2936  if(lb2>=0) {
2937  *pncase = 1;
2938  cases[0].lb1 = lb1, cases[0].ub1 = ub1, cases[0].lb2 = lb2, cases[0].ub2 = ub2, cases[0].positive_p = true;
2939  }
2940  else if(ub2<=0) {
2941  *pncase = 1;
2942  cases[0].lb1 = lb1, cases[0].ub1 = ub1, cases[0].lb2 = -ub2, cases[0].ub2 = -lb2, cases[0].positive_p = false;
2943  }
2944  else {
2945  // The second interval must be broken into two sub-intervals
2946  *pncase = 2;
2947  cases[0].lb1 = lb1, cases[0].ub1 = ub1, cases[0].lb2 = 1, cases[0].ub2 = -lb2, cases[0].positive_p = false;
2948  cases[1].lb1 = lb1, cases[1].ub1 = ub1, cases[1].lb2 = nlb, cases[1].ub2 = ub2, cases[1].positive_p = true;
2949  }
2950  }
2951  else if(ub1<=0) {
2952  // The first interval is negative
2953  if(lb2>=0) {
2954  *pncase = 1;
2955  cases[0].lb1 = -ub1, cases[0].ub1 = -lb1, cases[0].lb2 = lb2, cases[0].ub2 = ub2, cases[0].positive_p = false;
2956  }
2957  else if(ub2<=0) {
2958  *pncase = 1;
2959  cases[0].lb1 = -ub1, cases[0].ub1 = -lb1, cases[0].lb2 = -ub2, cases[0].ub2 = -lb2, cases[0].positive_p = true;
2960  }
2961  else {
2962  // The second interval must be broken into two sub-intervals
2963  *pncase = 2;
2964  cases[0].lb1 = -ub1, cases[0].ub1 = -lb1, cases[0].lb2 = 1, cases[0].ub2 = -lb2, cases[0].positive_p = true;
2965  cases[1].lb1 = -ub1, cases[1].ub1 = -lb1, cases[1].lb2 = nlb, cases[0].ub2 = ub2, cases[1].positive_p = false;
2966  }
2967  }
2968  else {
2969  // The first interval must be broken into two sub-intervals
2970  if(lb2>=0) {
2971  *pncase = 2;
2972  cases[0].lb1 = 1, cases[0].ub1 = -lb1, cases[0].lb2 = lb2, cases[0].ub2 = ub2, cases[0].positive_p = false;
2973  cases[1].lb1 = nlb, cases[1].ub1 = ub1, cases[1].lb2 = lb2, cases[1].ub2 = ub2, cases[1].positive_p = true;
2974  }
2975  else if(ub2<=0) {
2976  *pncase = 2;
2977  cases[0].lb1 = 1, cases[0].ub1 = -lb1, cases[0].lb2 = -ub2, cases[0].ub2 = -lb2, cases[0].positive_p = true;
2978  cases[1].lb1 = 1, cases[1].ub1 = ub1, cases[1].lb2 = -ub2, cases[1].ub2 = -lb2, cases[1].positive_p = false;
2979  }
2980  else {
2981  // The second interval must be broken into two sub-intervals
2982  *pncase = 4;
2983  cases[0].lb1 = 1, cases[0].ub1 = -lb1, cases[0].lb2 = 1, cases[0].ub2 = -lb2, cases[0].positive_p = true;
2984  cases[1].lb1 = nlb, cases[1].ub1 = ub1, cases[1].lb2 = 1, cases[1].ub2 = -lb2, cases[1].positive_p = false;
2985  cases[2].lb1 = 1, cases[2].ub1 = -lb1, cases[2].lb2 = nlb, cases[2].ub2 = ub2, cases[2].positive_p = false;
2986  cases[3].lb1 = nlb, cases[3].ub1 = ub1, cases[3].lb2 = nlb, cases[3].ub2 = ub2, cases[3].positive_p = true;
2987  }
2988  }
2989  }
2990  else {
2991  if(lb2>=0) {
2992  *pncase = 1;
2993  cases[0].lb1 = 1, cases[0].ub1 = 1, cases[0].lb2 = lb2, cases[0].ub2 = ub2, cases[0].positive_p = true;
2994  }
2995  else if(ub2<=0) {
2996  *pncase = 1;
2997  cases[0].lb1 = 1, cases[0].ub1 = 1, cases[0].lb2 = -ub2, cases[0].ub2 = -lb2, cases[0].positive_p = false;
2998  }
2999  else {
3000  // The v2 interval must be broken into two sub-intervals
3001  *pncase = 2;
3002  cases[0].lb1 = 1, cases[0].ub1 = 1, cases[0].lb2 = 1, cases[0].ub2 = -lb2, cases[0].positive_p = false;
3003  cases[1].lb1 = 1, cases[1].ub1 = 1, cases[1].lb2 = nlb, cases[1].ub2 = ub2, cases[1].positive_p = true;
3004  }
3005  }
3006 }
3007 */
3008 
3009 /* Equation v = v1/v2 for v1>=0 and v2>=0: v1-v2+1 <= v2 v <= v1
3010  *
3011  * We know positive bounds [lb1,ub1] for v1 and [lb2,ub2] for v2.
3012  * What do we know about v?
3013  *
3014  * v1-v2+1 <= v2 v <= v1
3015  *
3016  * The only non-affine term is v2 v:
3017  *
3018  * v1-v2+1 <= ub2 v => -ub2 v + v1 - v2 + 1 <= 0
3019  * lb2 v <= v1 => lb2 v -v1 <= 0
3020  *
3021  * If -v must be used instead of v:
3022  *
3023  * v1-v2+1 <= -ub2 v => ub2 v <= v2-v1-1 => ub2 v + v1 - v2 + 1 <= 0
3024  * -lb2 v <= v1 => lb2 v >= v1 => -lb2 v -v1 <= 0
3025  *
3026  * Else, we can also eliminate v1 and v2 everywhere.
3027  * Substitute v1 thanks to lb1 <= v1 <= ub1:
3028  * lb1-v2+1 <= v2 v <= ub1
3029  * Substitue the left v2 in the same way:
3030  * lb1-ub2+1 <= v2 v <= ub1
3031  * If lb2==ub2, v2 v is an affine term.
3032  * Else substitue the central v2 for each inequality:
3033  * lb2 v <= ub1 => v<= ub1/lb2
3034  * lb1-ub2+1 <=ub2 v => v>= lb1/ub2
3035  *
3036  * if the positive flag is not set, v must be replaced by -v:
3037  * -ub2 v <= ub1 => v>=-ub1/lb2
3038  * lb1-ub2+1<=-lb2 v => v<=-lb1/ub2
3039  */
3040 /* DEAD CODE
3041 static transformer process_interval_for_divide(
3042  entity v, entity v1, entity v2, struct interval_product one_case)
3043 {
3044  long long int lb1 = one_case.lb1;
3045  long long int ub1 = one_case.ub1;
3046  long long int lb2 = one_case.lb2;
3047  long long int ub2 = one_case.ub2;
3048  bool positive_p = one_case.positive_p;
3049  // Two possible options: true and false
3050  bool full_elimination = false;
3051  transformer itf = transformer_identity(); // no information at first
3052 
3053  if(full_elimination) {
3054  if(ub1 != INT_MAX && lb2 != INT_MAX) {
3055  if(positive_p)
3056  itf = transformer_add_inequality_with_integer_constraint(itf, v, ub1/lb2, true);
3057  else
3058  itf = transformer_add_inequality_with_integer_constraint(itf, v, -(ub1/lb2), false);
3059  }
3060 
3061  if(lb1 != INT_MAX && ub2 != INT_MAX && lb2 != INT_MAX) {
3062  if(positive_p)
3063  itf = transformer_add_inequality_with_integer_constraint(itf, v, lb1/ub2, false);
3064  else
3065  itf = transformer_add_inequality_with_integer_constraint(itf, v, -(lb1/ub2), true);
3066  }
3067  }
3068  else {
3069  // Minimize the number of substitutions:
3070  //
3071  // If v is positive because v1>=0 and v2 >=0
3072  //
3073  // v1 = v2 v + x ^ 0<=x<=v2-1 if v1 >= 0 && v2 >= 0
3074  // v1 <= v2 v + v2 -1 ^ v1>= v2 v ^ lb2 <= v2 <= ub2
3075  // v1-v2+1 <= ub2 v => -ub2 v + v1 - v2 + 1 <= 0
3076  // lb2 v <= v1 => lb2 v -v1 <= 0
3077  //
3078  // If v is negative because v1 <=0 and v2 >=0:
3079  //
3080  // v1 = v2 v + x ^ -v2+1<=x<=0 if v1 <= 0 && v2 >= 0
3081  // v1 <= v2 v ^ v1>= v2 v - v2 + 1
3082  // v1 <= lb2 v => -lb2 v + v1 <= 0
3083  // ub2 v -v2 +1 <= v1 => ub2 v -v1 -v2 + 1 <= 0
3084  //
3085  // If v2 <= 0, use -v2 and -v1?
3086  if(positive_p) {
3087  itf = transformer_add_3d_affine_constraint(itf, -ub2, v, 1, v1, -1, v2, 1, false);
3088  itf = transformer_add_3d_affine_constraint(itf, lb2, v, -1, v1, 0, v2, 0, false);
3089  }
3090  else {
3091  itf = transformer_add_3d_affine_constraint(itf, ub2, v, 1, v1, -1, v2, 1, false);
3092  itf = transformer_add_3d_affine_constraint(itf, -lb2, v, -1, v1, 0, v2, 0, false);
3093  }
3094  }
3095 
3096  return itf;
3097 }
3098 
3099 static transformer process_intervals_for_divide(
3100  transformer tf, entity v, entity v1, entity v2,
3101  struct interval_product cases[4], int ncase)
3102 {
3103  int i;
3104  transformer dtf = transformer_empty();
3105 
3106  if(false) {
3107  // Perform the convex hull before the intersection is faster but
3108  // less accurate in general, maybe not when v1 and v2 have been fully
3109  // eliminated.
3110  for(i=0; i<ncase; i++) {
3111  transformer itf = process_interval_for_divide(v, v1, v2, cases[i]);
3112  dtf = transformer_convex_hull(dtf, itf);
3113  }
3114  // To be checked for functionality and memory leaks
3115  tf = transformer_image_intersection(tf, dtf);
3116  }
3117  else {
3118  for(i=0; i<ncase; i++) {
3119  transformer itf = process_interval_for_divide(v, v1, v2, cases[i]);
3120  transformer ctf = transformer_combine(copy_transformer(tf), itf);
3121  free_transformer(itf);
3122  // memory leak
3123  transformer ndtf = transformer_convex_hull(dtf, ctf);
3124  free_transformer(dtf);
3125  free_transformer(ctf);
3126  dtf = ndtf;
3127  }
3128  // To be checked for functionality and memory leaks
3129  tf = dtf;
3130  }
3131 
3132  return tf;
3133 }
3134 */
3135 
3136 /* The equation v1 = v2 v + r is always true. But we need to eliminate
3137  * the remainder r which is implicit and to linearize the product v2 v
3138  * to obtain affine constraints of v, v1, v2, using constant lb1, ub1,
3139  * lb2 and ub2, with lb1 <= v1 <= ub1 and lb2 <= v2 <=ub2.
3140  */
3141 static transformer process_bounds_for_divide(transformer tf, entity v, entity v1, int lb1, int ub1, entity v2, int lb2, int ub2)
3142 {
3143  if(lb2==0&&ub2==0) { // zero divide
3144  semantics_user_warning("Zero divide:\n");
3145  free_transformer(tf);
3146  tf = transformer_empty();
3147  }
3148  else if(lb2>=0) { // division by a strictly positive number
3149  if(lb2==0)
3150  lb2 = 1;
3151  if(lb1>=0) { // of a positive number: divide01
3152  /* v2 is positive and r is positive: 0 <= r <= v2 - 1
3153  * v1 = v2 v + r
3154  * v1 <= v2 v + v2 - 1
3155  * v1 >= v2 v
3156  * lb2 <= v2 <= ub2 => lb2 v <= v2 v <= ub2 v
3157  * => v1 <= ub2 v + v2 -1 => -ub2 v + v1 - v2 + 1 <= 0
3158  * => v1 >= lb2 v => lb2 v - v1 <=0
3159  */
3160  if(ub2!=INT_MAX)
3161  tf = transformer_add_3d_affine_constraint(tf, -ub2, v, 1, v1, -1, v2, 1, false);
3162  else
3163  tf = transformer_add_3d_affine_constraint(tf, -1, v, 0, v1, 0, v2, 0, false);
3164  tf = transformer_add_3d_affine_constraint(tf, lb2, v, -1, v1, 0, v2, 0, false);
3165  }
3166  else if(ub1<=0) { // of a negative number: divide02
3167  /* v2 is positive and r is negative: -v2 + 1 <= r <= 0
3168  * v1 = v2 v + r
3169  * v1 <= v2 v
3170  * v1 >= v2 v - v2 + 1
3171  * lb2 <= v2 <= ub2 => ub2 v <= v2 v <= lb2 v
3172  * => v1 <= lb2 v => -lb2 v + v1 <= 0
3173  * => v1 >= ub2 v -v2 + 1 => ub2 v - v1 -v2 + 1 <=0
3174  */
3175  tf = transformer_add_3d_affine_constraint(tf, -lb2, v, 1, v1, 0, v2, 0, false);
3176  if(ub2!=INT_MAX)
3177  tf = transformer_add_3d_affine_constraint(tf, ub2, v, -1, v1, -1, v2, 1, false);
3178  else
3179  tf = transformer_add_3d_affine_constraint(tf, 1, v, 0, v1, 0, v2, 0, false);
3180  }
3181  else { // of a number of unknown sign
3182  /* v2 is positive and r is bounded: -v2 + 1 <= r <= v2 - 1
3183  * v1 = v2 v + r
3184  * v1 <= v2 v + v2 - 1
3185  * v1 >= v2 v - v2 + 1
3186  * I do not know how to linearize v2 v, unless v2 is a constant,
3187  * but v1/v2 can be bounded:
3188  * lb1 <= v1 <= ub1 => lb1/v2 <= v1/v2 <= ub1/v2 => lb1/lb2 <= v <= ub1/lb2
3189  *
3190  * Also, when v2 is a numerical constant, if exists x s.t. v1 ==
3191  * v2 x, then v == x. This is not exploited here.
3192  */
3193  if(lb2==ub2) { // v2 v is a linear term, Semantics-New/S124, divide07
3194  // - v2 v + v1 - v2 + 1 <=0
3195  tf = transformer_add_3d_affine_constraint(tf, -lb2, v, 1, v1, -1, v2, 1, false);
3196  // v2 v - v1 - v2 +1 <=0
3197  tf = transformer_add_3d_affine_constraint(tf, lb2, v, -1, v1, -1, v2, 1, false);
3198  }
3199  if(lb1!=INT_MIN)
3200  tf = transformer_add_3d_affine_constraint(tf, -1, v, 0, v1, 0, v2, lb1/lb2, false);
3201  if(ub1!=INT_MAX)
3202  tf = transformer_add_3d_affine_constraint(tf, 1, v, 0, v1, 0, v2, ub1/lb2, false);
3203  }
3204  }
3205  else if(ub2<=0) { // division by a strictly negative number
3206  if(ub2==0)
3207  ub2 = -1;
3208  if(lb1>=0) { // of a positive number, e.g. 100/-3 = -33 (r=1), divide03
3209  /* v2 is negative and r is positive: 0 <= r <= -v2 - 1
3210  * v1 = v2 v + r
3211  * v1 <= v2 v - v2 - 1
3212  * v1 >= v2 v
3213  * lb2 <= v2 <= ub2 => ub2 v <= v2 v <= lb2 v (since v is negative)
3214  * => v1 <= lb2 v - v2 -1 => -lb2 v + v1 + v2 + 1 <= 0
3215  * => v1 >= ub2 v => ub2 v - v1 <=0
3216  */
3217  if(lb2!=INT_MAX)
3218  tf = transformer_add_3d_affine_constraint(tf, -lb2, v, 1, v1, 1, v2, 1, false);
3219  else
3220  tf = transformer_add_3d_affine_constraint(tf, 1, v, 0, v1, 0, v2, 0, false);
3221  tf = transformer_add_3d_affine_constraint(tf, ub2, v, -1, v1, 0, v2, 0, false);
3222  }
3223  else if(ub1<=0) {// of a negative number, e.g. -100/-3 = 33 (r=-1), divide04
3224  /* v2 is negative and r is negative: v2 + 1 <= r <= 0
3225  * v1 = v2 v + r
3226  * v1 <= v2 v
3227  * v1 >= v2 v + v2 + 1
3228  * lb2 <= v2 <= ub2 => lb2 v <= v2 v <= ub2 v (since v is positive)
3229  * => v1 <= ub2 v => -ub2 v + v1 <= 0
3230  * => v1 >= lb2 v + v2 + 1 => lb2 v - v1 + v2 + 1 <=0
3231  */
3232  tf = transformer_add_3d_affine_constraint(tf, -ub2, v, 1, v1, 0, v2, 0, false);
3233  if(lb2!=INT_MIN)
3234  tf = transformer_add_3d_affine_constraint(tf, lb2, v, -1, v1, 1, v2, 1, false);
3235  else
3236  tf = transformer_add_3d_affine_constraint(tf, -1, v, 0, v1, 0, v2, 0, false);
3237  }
3238  else { // of a number of unknown sign
3239  /* v2 is negative and r is bounded: v2 + 1 <= r <= -v2 - 1
3240  * v1 = v2 v + r
3241  * v1 <= v2 v - v2 - 1 => -v2 v + v1 + v2 + 1 <= 0
3242  * v1 >= v2 v + v2 + 1 => v2 v - v1 + v2 + 1 <=0
3243  * I do not know how to linearize v2 v, but v1/v2 can be bounded:
3244  * lb1 <= v1 <= ub1 => lb1/v2 >= v1/v2 >= ub1/v2 => ub1/ub2 <= v <= lb1/ub2
3245  */
3246  if(lb2==ub2) {
3247  tf = transformer_add_3d_affine_constraint(tf, -lb2, v, 1, v1, 1, v2, 1, false);
3248  tf = transformer_add_3d_affine_constraint(tf, lb2, v, -1, v1, 1, v2, 1, false);
3249  }
3250  if(ub1!=INT_MAX)
3251  tf = transformer_add_3d_affine_constraint(tf, -1, v, 0, v1, 0, v2, ub1/ub2, false);
3252  if(lb1!=INT_MIN)
3253  tf = transformer_add_3d_affine_constraint(tf, 1, v, 0, v1, 0, v2, -lb1/ub2, false);
3254  }
3255  }
3256  else { // No sign information is available for v1 or v2
3257  /* We are left with dividing interval [lb1, ub1] by interval [lb2,
3258  * ub2] knowing that lb1 and lb2 are negative and ub1 and ub2
3259  * positive. Since 1 and -1 belongs to [lb2, ub2], the upper bound
3260  * is max(ub1, -lb1) and the lower bound is min(-ub1, lb1).
3261  */
3262  if(lb1!=INT_MIN && ub1!=INT_MAX) { // divide05, divide06
3263  int u = ub1>=-lb1? ub1: -lb1;
3264  int l = -ub1<=lb1? -ub1: lb1;
3265  // l <= v <= u
3266  tf = transformer_add_3d_affine_constraint(tf, 1, v, 0, v1, 0, v2, -u, false);
3267  tf = transformer_add_3d_affine_constraint(tf, -1, v, 0, v1, 0, v2, l, false);
3268  }
3269  }
3270  return tf;
3271 }
3272 
3273 
3275  entity op,
3276  expression e1,
3277  expression e2,
3278  transformer pre,
3279  bool is_internal)
3280 {
3282 
3283  pips_debug(8, "Begin\n");
3284 
3285  if(ENTITY_PLUS_P(op) || ENTITY_MINUS_P(op)
3286  || ENTITY_PLUS_C_P(op) || ENTITY_MINUS_C_P(op)) {
3287  tf = addition_operation_to_transformer(e, e1, e2, pre,
3288  ENTITY_PLUS_P(op) || ENTITY_PLUS_C_P(op),
3289  is_internal);
3290  }
3292  tf = update_operation_to_transformer(e, op, e1, e2, pre, is_internal);
3293  }
3294  else if(ENTITY_MULTIPLY_P(op)) {
3295  tf = integer_multiply_to_transformer(e, e1, e2, pre, is_internal);
3296  }
3297  else if(ENTITY_MODULO_P(op) || ENTITY_C_MODULO_P(op)) {
3298  tf = modulo_to_transformer(e, e1, e2, pre, is_internal);
3299  }
3300  else if(ENTITY_DIVIDE_P(op)) {
3301  if(!get_bool_property("SEMANTICS_ASSUME_POSITIVE_REMAINDERS")) {
3302  /* Prologue more or less necessary for all non affine operators */
3303  entity v = e; // Formal parameter name should be fixed
3306  transformer t1 = safe_integer_expression_to_transformer(v1, e1, pre1, is_internal);
3309  transformer t2 = safe_integer_expression_to_transformer(v2, e2, pre2, is_internal);
3310 
3311  if(transformer_empty_p(t1) || transformer_empty_p(t2)) {
3312  // Some exception occurs during the evaluation of e1 or e2
3313  // For instance, a zero divide or an exit in a called function
3314  tf = transformer_empty();
3315  }
3316  else if(!transformer_undefined_p(t1) && !transformer_undefined_p(t2)) {
3317  int lb1 = 0, ub1 = 0, lb2 = 0, ub2 = 0;
3318  tf = transformer_combine(copy_transformer(t1), t2);
3319  /* post1 == pre2... */
3320  transformer post1 = transformer_range(transformer_apply(pre1, t1));
3321  transformer post2 = transformer_range(transformer_apply(post1, t2));
3322  // transformer post2 = transformer_range(tf);
3325 
3326  /* Case disjunction to use only positive intervals + sign information */
3327  //struct interval_product cases[4];
3328  //int ncase = 0;
3329  //break_intervals_into_positive_intervals(lb1, ub1, lb2, ub2, cases, &ncase, true);
3330  //tf = process_intervals_for_divide(tf, v, v1, v2, cases, ncase);
3331  tf = process_bounds_for_divide(tf, v, v1, lb1, ub1, v2, lb2, ub2);
3332  }
3333  else {
3334  /* either t1 or t2 is undefined: so tf is most likely undefined */
3335  ;
3336  }
3337  }
3338  else {
3339  /* Old function call */
3340  tf = integer_divide_to_transformer(e, e1, e2, pre, is_internal);
3341  }
3342  }
3343  else if(ENTITY_POWER_P(op)) {
3344  tf = integer_power_to_transformer(e, e1, e2, pre, is_internal);
3345  }
3346  else if(ENTITY_ASSIGN_P(op)) {
3347  tf = assign_operation_to_transformer(e, e1, e2, pre);
3348  }
3349  else if(ENTITY_LEFT_SHIFT_P(op)) {
3350  tf = integer_left_shift_to_transformer(e, e1, e2, pre, is_internal);
3351  }
3352  else if(ENTITY_RIGHT_SHIFT_P(op)) {
3353  tf = integer_right_shift_to_transformer(e, e1, e2, pre, is_internal);
3354  }
3355 
3356  pips_debug(8, "End with tf=%p\n", tf);
3357 
3358  return tf;
3359 }
3360 
3362  entity e,
3363  expression expr, /* needed to compute effects for user calls */
3364  transformer pre, /* Predicate on current store assumed not modified by
3365  expr's side effects */
3366  bool is_internal)
3367 {
3368  syntax sexpr = expression_syntax(expr);
3369  call c = syntax_call(sexpr);
3370  entity f = call_function(c);
3371  list args = call_arguments(c);
3373  int arity = gen_length(args);
3374 
3375  pips_debug(8, "Begin with precondition %p\n", pre);
3376 
3377  /* tests are organized to trap 0-ary user-defined functions as well as
3378  binary min and max */
3379 
3380  // arity unknown, but greater than 2?
3381  if(ENTITY_MIN0_P(f) || ENTITY_MIN_P(f)) {
3382  tf = min0_to_transformer(e, args, pre, is_internal);
3383  }
3384  else if(ENTITY_C_MIN_P(f)) {
3385  args=CDR(args);
3386  --arity;
3387  tf = min0_to_transformer(e,args,pre,is_internal);
3388  }
3389  else if(ENTITY_MAX0_P(f) || ENTITY_MAX_P(f)) {
3390  tf = max0_to_transformer(e, args, pre, is_internal);
3391  }
3392  else if(ENTITY_C_MAX_P(f)) {
3393  args=CDR(args);
3394  --arity;
3395  tf = max0_to_transformer(e,args,pre,is_internal);
3396  }
3397  else if(ENTITY_COMMA_P(f)) {
3398  // is_internal is dropped...
3399  tf = any_expressions_to_transformer(e, args, pre);
3400  }
3401  // arity==3
3402  else if(ENTITY_CONDITIONAL_P(f)) {
3403  tf = any_conditional_to_transformer(e, args, pre);
3404  }
3405  // arity==1
3406  else if(ENTITY_NOT_P(f)) {
3407  /* FI: should only happen for C code because int are often used
3408  as bool since there was no other way before C99. Quite time
3409  consuming here because it is applied to an int and not a
3410  bool argument. */
3411  tf = logical_not_to_transformer(e, args, pre);
3412  }
3413  // arity==2
3414  else if(ENTITY_BITWISE_XOR_P(f)) {
3415  /* FI: it might be useful to handle here the bit wise XOR as in
3416  logical_binary_operation_to_transformer(). */
3417  tf = bitwise_xor_to_transformer(e, args, pre);
3418  }
3419  // arity ==1
3420  else if(ENTITY_RAND_P(f)) {
3421  tf = transformer_identity();
3423  }
3424  // arity = 2
3425  else if(ENTITY_MODULO_P(f) || ENTITY_C_MODULO_P(f)) {
3426  expression arg1 = EXPRESSION(CAR(args));
3427  expression arg2 = EXPRESSION(CAR(CDR(args)));
3428  tf = modulo_to_transformer(e, arg1, arg2, pre, false);
3429  }
3430  else if(value_code_p(entity_initial(f))) {
3432  tf = user_function_call_to_transformer(e, expr, pre);
3433  }
3434  else {
3435  /* No need to use effects here. It will be done at a higher level */
3436  ;
3437  }
3438  }
3439  else if(arity==0) {
3440  /* integer constant must have been detected earlier as linear (affine)
3441  expressions but there might be nullary intrinsic such as rand() */
3442  tf = integer_nullary_operation_to_transformer(e, f, pre, is_internal);
3443  }
3444  else if(arity==1) {
3445  expression e1 = EXPRESSION(CAR(args));
3446  tf = integer_unary_operation_to_transformer(e, f, e1, pre, is_internal);
3447  }
3448  else if(arity==2) {
3450  && constant_path_analyzed_p()) {
3451  tf = lhs_expression_to_transformer(e, expr, pre);
3452  }
3453  else {
3454  expression e1 = EXPRESSION(CAR(args));
3455  expression e2 = EXPRESSION(CAR(CDR(args)));
3456  tf = integer_binary_operation_to_transformer(e, f, e1, e2, pre, is_internal);
3457  }
3458  }
3459 
3460  pips_debug(8, "End with tf=%p\n", tf);
3461 
3462  return tf;
3463 }
3464 
3466 {
3467  //list el = expression_to_proper_effects(expr);
3470 
3471  gen_full_free_list(el);
3472  return tf;
3473 }
3474 
3477  entity v,
3478  expression expr,
3479  transformer pre,
3480  bool is_internal) /* Do check wrt to value mappings... if you are
3481  not dealing with interprocedural issues */
3482 {
3484  normalized n = NORMALIZE_EXPRESSION(expr);
3485  syntax sexpr = expression_syntax(expr);
3486 
3487  pips_debug(8, "begin with precondition %p for expression: ", pre);
3488  ifdebug(8) print_expression(expr);
3489 
3490  /* Assume: e is a value */
3491 
3492  if(normalized_linear_p(n)) {
3493  /* Is it really useful to keep using this function which does not
3494  take the precondition into acount? */
3495  if(transformer_undefined_p(pre)) {
3496  tf = simple_affine_to_transformer(v, (Pvecteur) normalized_linear(n), is_internal);
3497  }
3498  else {
3500  if(transformer_undefined_p(tfl)) {
3502  }
3503 
3504  tf = transformer_combine(copy_transformer(pre), tfl);
3505  free_transformer(tfl);
3506  }
3507  }
3508  else if(syntax_call_p(sexpr)) {
3509  tf = integer_call_expression_to_transformer(v, expr, pre, is_internal);
3510  }
3511  else if(syntax_reference_p(sexpr)) {
3512  //entity e = reference_variable(syntax_reference(sexpr));
3513  reference r = syntax_reference(sexpr);
3514  tf = generic_reference_to_transformer(v, r, pre, is_internal);
3515  }
3516  else if(syntax_cast_p(sexpr)) {
3517  cast c = syntax_cast(sexpr);
3518  type ct = cast_type(c);
3519  expression cexp = cast_expression(c);
3520  type cexpt = expression_to_type(cexp);
3521  if (type_equal_p(ct, cexpt))
3522  tf = integer_expression_to_transformer(v, cexp, pre, is_internal);
3523  else
3524  tf = transformer_undefined;
3525  free_type(cexpt);
3526 
3527  }
3528  else if(syntax_sizeofexpression_p(sexpr)) {
3529  if(get_bool_property("EVAL_SIZEOF")) {
3531  value val = EvalSizeofexpression(soe);
3532  if(value_constant_p(val) && constant_int_p(value_constant(val))) {
3533  long long int i = constant_int(value_constant(val));
3534  tf = transformer_identity();
3536  }
3537  }
3538  else
3539  tf = transformer_undefined;
3540  }
3541  else {
3542  /* vect_rm(ve); */
3543  tf = transformer_undefined;
3544  }
3545 
3546  pips_debug(8, "end with tf=%p\n", tf);
3547 
3548  return tf;
3549 }
3550 
3551 /* Always return a defined transformer, using effects in case a more precise analysis fails */
3553  entity v,
3554  expression expr,
3555  transformer pre,
3556  bool is_internal) /* Do check wrt to value mappings... if you are
3557  not dealing with interprocedural issues */
3558 {
3559  transformer tf = integer_expression_to_transformer(v, expr, pre, is_internal);
3560 
3561  if(transformer_undefined_p(tf))
3563 
3564  return tf;
3565 }
3566 ␌
3567 /* PROCESSING OF LOGICAL EXPRESSIONS */
3568 
3570 {
3571  /* the values of v are between 0 and 1 */
3572  Pvecteur ineq1 = vect_new((Variable) v, VALUE_ONE);
3573  Pvecteur ineq2 = vect_new((Variable) v, VALUE_MONE);
3574 
3575  vect_add_elem(&ineq1, TCST, VALUE_MONE);
3576 
3577  tf = transformer_inequality_add(tf, ineq1);
3578  tf = transformer_inequality_add(tf, ineq2);
3579 
3580  return tf;
3581 }
3582 
3584  entity f)
3585 {
3588  Pcontrainte c;
3589 
3590  if(ENTITY_TRUE_P(f) || ENTITY_ONE_P(f)) {
3592  }
3593  else if(ENTITY_FALSE_P(f) || ENTITY_ZERO_P(f)) {
3594  ;
3595  }
3596  else {
3597  pips_internal_error("Unknown logical constant %s",
3598  entity_name(f));
3599  }
3600  c = contrainte_make(eq);
3601  tf = make_transformer(NIL,
3603 
3604  return tf;
3605 }
3606 
3608  call c,
3609  transformer pre,
3610  bool is_internal)
3611 {
3613  entity op = call_function(c);
3616 
3617  /* pips_assert("A unique argument", ENDP(CDR(call_arguments(c)))); */
3618 
3619  if(ENTITY_NOT_P(op)) {
3621  tf = logical_expression_to_transformer(tmp, arg, pre, is_internal);
3622  vect_add_elem(&eq, (Variable) tmp , VALUE_ONE);
3624  }
3625  else {
3626 // pips_internal_error("Unknown logical constant %s",
3627 // entity_name(op));
3628  }
3629  tf = transformer_equality_add(tf, eq);
3631 
3632  if(transformer_undefined_p(tf)) {
3633  semantics_user_warning("Not tested for logical.\n");
3634  //tf = points_to_unary_operation_to_transformer(v, op, arg, pre, is_internal, false);
3635  tf = generic_unary_operation_to_transformer(v, op, arg, pre, is_internal);
3636  }
3637 
3638  return tf;
3639 }
3640 
3642  call c,
3643  transformer pre,
3644  bool is_internal)
3645 {
3646  entity op = call_function(c);
3647  Pvecteur eq1 = VECTEUR_NUL;
3648  Pvecteur eq2 = VECTEUR_NUL;
3649  Pvecteur eq3 = VECTEUR_NUL;
3650  Pvecteur eq4 = VECTEUR_NUL;
3655  transformer tf1 = logical_expression_to_transformer(tmp1, arg1, pre, is_internal);
3656  transformer tf2 = logical_expression_to_transformer(tmp2, arg2, pre, is_internal);
3658 
3659  ifdebug(9) {
3660  pips_debug(9, "Begin for value %s with subtransformers:\n",
3661  entity_name(v));
3662  dump_transformer(tf1);
3663  dump_transformer(tf2);
3664  }
3665 
3666  free_transformer(tf1);
3667  free_transformer(tf2);
3668 
3669  ifdebug(9) {
3670  pips_debug(9, "Union of subtransformers:\n");
3671  dump_transformer(tf);
3672  }
3673 
3674  if(!transformer_undefined_p(tf)) {
3675  if(ENTITY_AND_P(op)) {
3676  /* v <= tmp1, v <= tmp2, v >= tmp1+tmp2-1 */
3677  eq1 = vect_new((Variable) v, VALUE_ONE);
3678  vect_add_elem(&eq1, (Variable) tmp1, VALUE_MONE);
3679  eq2 = vect_new((Variable) v, VALUE_ONE);
3680  vect_add_elem(&eq2, (Variable) tmp2, VALUE_MONE);
3681  eq3 = vect_new((Variable) v, VALUE_MONE);
3682  vect_add_elem(&eq3, (Variable) tmp1, VALUE_ONE);
3683  vect_add_elem(&eq3, (Variable) tmp2, VALUE_ONE);
3684  vect_add_elem(&eq3, TCST, VALUE_MONE);
3685  }
3686  else if(ENTITY_OR_P(op)) {
3687  /* v >= tmp1, v>= tmp2, v <= tmp1+tmp2 */
3688  eq1 = vect_new((Variable) v, VALUE_MONE);
3689  vect_add_elem(&eq1, (Variable) tmp1, VALUE_ONE);
3690  eq2 = vect_new((Variable) v, VALUE_MONE);
3691  vect_add_elem(&eq2, (Variable) tmp2, VALUE_ONE);
3692  eq3 = vect_new((Variable) v, VALUE_ONE);
3693  vect_add_elem(&eq3, (Variable) tmp1, VALUE_MONE);
3694  vect_add_elem(&eq3, (Variable) tmp2, VALUE_MONE);
3695  }
3696  else if(ENTITY_EQUAL_P(op)) {
3697  /* v >= 1-tmp1-tmp2, v >= tmp1+tmp2-1, i.e.
3698  * -v -tmp1 -tmp2 + 1 <= 0, -v+tmp1+tmp2-1<=0
3699  * v <= 1-tmp1+tmp2, v <= 1+tmp1-tmp2, i.e.
3700  * v + tmp1 - tmp2 - 1 <= 0, v - tmp1 + tmp2 - 1 <=0
3701  */
3702  eq1 = vect_new((Variable) v, VALUE_MONE);
3703  vect_add_elem(&eq1, (Variable) tmp1, VALUE_MONE);
3704  vect_add_elem(&eq1, (Variable) tmp2, VALUE_MONE);
3705  vect_add_elem(&eq1, TCST , VALUE_ONE);
3706 
3707  eq2 = vect_new((Variable) v, VALUE_MONE);
3708  vect_add_elem(&eq2, (Variable) tmp1, VALUE_ONE);
3709  vect_add_elem(&eq2, (Variable) tmp2, VALUE_ONE);
3710  vect_add_elem(&eq2, TCST , VALUE_MONE);
3711 
3712  eq3 = vect_new((Variable) v, VALUE_ONE);
3713  vect_add_elem(&eq3, (Variable) tmp1, VALUE_ONE);
3714  vect_add_elem(&eq3, (Variable) tmp2, VALUE_MONE);
3715  vect_add_elem(&eq3, TCST , VALUE_MONE);
3716 
3717  eq4 = vect_new((Variable) v, VALUE_ONE);
3718  vect_add_elem(&eq4, (Variable) tmp1, VALUE_MONE);
3719  vect_add_elem(&eq4, (Variable) tmp2, VALUE_ONE);
3720  vect_add_elem(&eq4, TCST , VALUE_MONE);
3721  }
3722  else if(ENTITY_NON_EQUAL_P(op) || ENTITY_BITWISE_XOR_P(op)) {
3723  /* v <= tmp1+tmp2, v <= 2-tmp1-tmp2, i.e.
3724  * v - tmp 1 - tmp 2 <= 0, v -tmp1-tmp2 -2 <= 0
3725  * v >= tmp1 - tmp2, v >= -tmp1+tmp2, i.e.
3726  * -v + tmp1 - tmp2 <=0, -v - tmp1 + tmp2 <=0
3727  */
3728  eq1 = vect_new((Variable) v, VALUE_ONE);
3729  vect_add_elem(&eq1, (Variable) tmp1, VALUE_MONE);
3730  vect_add_elem(&eq1, (Variable) tmp2, VALUE_MONE);
3731 
3732  eq2 = vect_new((Variable) v, VALUE_ONE);
3733  vect_add_elem(&eq2, (Variable) tmp1, VALUE_ONE);
3734  vect_add_elem(&eq2, (Variable) tmp2, VALUE_ONE);
3736 
3737  eq3 = vect_new((Variable) v, VALUE_MONE);
3738  vect_add_elem(&eq3, (Variable) tmp1, VALUE_ONE);
3739  vect_add_elem(&eq3, (Variable) tmp2, VALUE_MONE);
3740 
3741  eq4 = vect_new((Variable) v, VALUE_MONE);
3742  vect_add_elem(&eq4, (Variable) tmp1, VALUE_MONE);
3743  vect_add_elem(&eq4, (Variable) tmp2, VALUE_ONE);
3744 
3745  }
3746  else {
3747  pips_internal_error("Unexpected binary logical operator %s",
3748  entity_name(op));
3749  }
3750  tf = transformer_inequality_add(tf, eq1);
3751  tf = transformer_inequality_add(tf, eq2);
3752  if(!VECTEUR_NUL_P(eq3)) {
3753  if(!VECTEUR_NUL_P(eq4)) {
3754  tf = transformer_inequality_add(tf, eq4);
3755  }
3756  tf = transformer_inequality_add(tf, eq3);
3757  }
3759  }
3760 
3761  ifdebug(9) {
3762  pips_debug(9, "End with transformer:\n");
3763  dump_transformer(tf);
3764  }
3765 
3766  return tf;
3767 }
3768 
3770  call c,
3771  transformer pre,
3772  bool is_internal)
3773 {
3775  entity op = call_function(c);
3776 
3777  if(ENTITY_AND_P(op)||ENTITY_OR_P(op)||ENTITY_EQUAL_P(op)
3780  tf = logical_binary_operation_to_transformer(v, c, pre, is_internal);
3781  }
3782  else if(ENTITY_ASSIGN_P(op)) {
3783  /* FI: slight signature mismatch: no need to propagate the call
3784  once you know it is a binary operator... */
3785  list args = call_arguments(c);
3786  expression lhs = EXPRESSION(CAR(args));
3787  expression rhs = EXPRESSION(CAR(CDR(args)));
3788  tf = assign_operation_to_transformer(v, lhs, rhs, pre);
3789  }
3790  else if(ENTITY_RELATIONAL_OPERATOR_P(op)) {
3791  expression expr1 = EXPRESSION(CAR(call_arguments(c)));
3792  expression expr2 = EXPRESSION(CAR(CDR(call_arguments(c))));
3793  basic b1 = basic_of_expression(expr1);
3794  basic b2 = basic_of_expression(expr2);
3795 
3797  tf = logical_binary_operation_to_transformer(v, c, pre, is_internal);
3798  }
3799  else if(!transformer_undefined_p(pre)) {
3800  /* Non internal overloaded functions such as EQ, NEQ, GE, GT, LE, LT,... */
3801  //entity tmp = make_local_temporary_value_entity(entity_type(v));
3803  op,
3804  expr1,
3805  expr2,
3806  pre,
3807  true,
3808  true);
3809 
3810  // The normalization of tfe and tfne below is key because
3811  // transformer_empty_p() is quite weak (but fast) [FI: transformer_is_empty_p]
3812  tfe = transformer_normalize(tfe, 2);
3813  /* if the transformer is not feasible, return false */
3814  if(transformer_empty_p(tfe)) {
3816  Pcontrainte c;
3817 
3818  c = contrainte_make(eq);
3819  tf = make_transformer(NIL,
3821  }
3822  else {
3824  op,
3825  expr1,
3826  expr2,
3827  pre,
3828  false,
3829  true);
3830 
3831  tfne = transformer_normalize(tfne, 2);
3832  /* if the transformer is not feasible, return true */
3833  if(transformer_empty_p(tfne)) {
3835  Pcontrainte c;
3836 
3838  c = contrainte_make(eq);
3839  tf = make_transformer(NIL,
3841  }
3842  free_transformer(tfne);
3843  }
3844  free_transformer(tfe);
3845  }
3846  else {
3847  ;
3848  }
3849 
3850  free_basic(b1);
3851  free_basic(b2);
3852  }
3853  else {
3854  /* general case due to C convention about integers equal to 0 or
3855  * not.
3856  *
3857  * if v is in [0..1], v can be used as such.
3858  * else if v>0, return 1
3859  * else if v<0, return 1
3860  * else 0<=v<=1
3861  */
3864  tf = integer_binary_operation_to_transformer(v, op, e1, e2,
3865  pre, is_internal);
3866  if(!transformer_undefined_p(tf)) {
3867  // FI: should we restrict us to the range of tf?
3868  intptr_t vmin, vmax;
3869  bool success = precondition_minmax_of_value(v, tf, &vmin, &vmax);
3870  if(success) {
3871  if(vmin>=0 && vmax<=1)
3872  ; // tf can be returned as such
3873  else if(vmin>=1 || vmax<=-1) {
3874  // Must return v==1
3875  free_transformer(tf);
3876  tf = transformer_identity();
3878  }
3879  }
3880  }
3881 
3882  if(transformer_undefined_p(tf)) {
3883  // Must return 0<=v<=1
3884  tf = transformer_identity();
3887  }
3888  }
3889 
3890  return tf;
3891 }
3892 
3893 /* v is assumed to be a temporary value and r a logical program variable */
3895  entity r,
3896  bool is_internal)
3897 {
3899 
3900  if(!is_internal || entity_has_values_p(r)) {
3901  entity r_new = is_internal? entity_to_new_value(r) : external_entity_to_new_value(r);
3902 
3903 
3904  tf = simple_equality_to_transformer(v, r_new, false);
3905  tf = transformer_logical_inequalities_add(tf, r_new);
3906  }
3907 
3908  return tf;
3909 }
3910 
3912  call c,
3913  transformer pre,
3914  bool is_internal)
3915 {
3917 
3918  switch(gen_length(call_arguments(c))) {
3919  case 0:
3921  break;
3922  case 1:
3923  tf = logical_unary_operation_to_transformer(v, c, pre, is_internal);
3924  break;
3925  case 2:
3926  tf = logical_binary_function_to_transformer(v, c, pre, is_internal);
3927  break;
3928  default:
3929  pips_internal_error("Too many logical arguments, %d, for operator %s",
3932  }
3933  return tf;
3934 }
3935 
3936 /* Could be used to compute preconditions too. v is assumed to be a new
3937  value or a temporary value. */
3939  expression rhs,
3940  transformer pre,
3941  bool is_internal)
3942 {
3944  syntax srhs = expression_syntax(rhs);
3945 
3946  switch(syntax_tag(srhs)) {
3947  case is_syntax_call: {
3948  call c = syntax_call(srhs);
3949  entity f = call_function(c);
3950  if(intrinsic_entity_p(f))
3951  tf = logical_intrinsic_to_transformer(v, c, pre, is_internal);
3952  else if(call_constant_p(c)) {
3953  entity cf = call_function(c);
3954  int i;
3955  if(logical_constant_p(cf)) {
3956  /* Is likely to be handled as a nullary intrinsics */
3957  tf = logical_intrinsic_to_transformer(v, c, pre, is_internal);
3958  }
3959  else if(integer_constant_p(cf, &i)) {
3960  if(i!=0)
3961  i = 1;
3962  tf = transformer_identity();
3964  }
3965  else
3966  pips_internal_error("Unexpected case.\n");
3967  }
3968  else {
3969  // call to a C or Fortran bool function
3970  //list ef = expression_to_proper_effects(rhs);
3971  tf = user_function_call_to_transformer(v, rhs, pre);
3972  }
3973  break;
3974  }
3975  case is_syntax_reference: {
3976  // FI: information in precondition pre is lost here
3978  is_internal);
3980  // FI: let us assume that pre is a range, not a transformer
3981  tf = transformer_intersection(rtf, pre);
3982  }
3983  break;
3984  }
3985  case is_syntax_range:
3986  pips_internal_error("Unexpected tag %d", syntax_tag(srhs));
3987  break;
3988  default:
3989  pips_internal_error("Illegal tag %d", syntax_tag(srhs));
3990  }
3991  return tf;
3992 }
3993 ␌
3995  expression rhs)
3996 {
3998  syntax srhs = expression_syntax(rhs);
3999 
4000  switch(syntax_tag(srhs)) {
4001  case is_syntax_call:
4002  switch(gen_length(call_arguments(syntax_call(srhs)))) {
4003  case 0:
4004  /* tf = constant_to_transformer(v, call_function(syntax_call(srhs))); */
4005  tf = constant_to_transformer(v, rhs);
4006  break;
4007  case 1:
4008  break;
4009  case 2:
4010  break;
4011  case 3:
4012  break;
4013  default:
4014  pips_internal_error("Too many arguments, %d, for operator %s",
4017  }
4018  break;
4019  case is_syntax_reference:
4020  {
4022 
4023  if(entity_has_values_p(r)) {
4026 
4027  if(basic_string_p(bv) && basic_string_p(br)) {
4028  int llhs = string_type_size(bv);
4029  int lrhs = string_type_size(br);
4030 
4031  if(llhs == -1 || llhs >= lrhs) {
4032  entity r_new = entity_to_new_value(r);
4033  tf = simple_equality_to_transformer(v, r_new, false);
4034  }
4035  }
4036  else {
4037  pips_user_error("Incompatible type in CHARACTER assignment: %s\n",
4038  basic_to_string(br));
4039  }
4040  }
4041  break;
4042  }
4043  case is_syntax_range:
4044  pips_internal_error("Unexpected tag %d", syntax_tag(srhs));
4045  break;
4046  default:
4047  pips_internal_error("Illegal tag %d", syntax_tag(srhs));
4048  }
4049 
4050  return tf;
4051 }
4052 ␌
4053 static transformer
4055  entity e,
4056  entity op,
4057  expression e1,
4058  transformer pre,
4059  bool is_internal)
4060 {
4062 
4063  tf = generic_unary_operation_to_transformer(e, op, e1, pre, is_internal);
4064 
4065  if(transformer_undefined_p(tf)) {
4066  // tf = points_to_unary_operation_to_transformer(e, op, e1, pre, is_internal, false);
4067  tf = generic_unary_operation_to_transformer(e, op, e1, pre, is_internal);
4068  }
4069 
4070  return tf;
4071 }
4072 
4073 static transformer
4075  entity e,
4076  entity op,
4077  expression e1,
4078  expression e2,
4079  transformer pre,
4080  bool is_internal)
4081 {
4083 
4084  if(ENTITY_PLUS_P(op) || ENTITY_MINUS_P(op)) {
4085  tf = addition_operation_to_transformer(e, e1, e2, pre, ENTITY_PLUS_P(op), is_internal);
4086  }
4087  else if(ENTITY_ASSIGN_P(op)) {
4088  tf = assign_operation_to_transformer(e, e1, e2, pre);
4089  }
4090 
4091  return tf;
4092 }
4093 
4094 static transformer
4096  entity v,
4097  expression expr, /* needed to compute effects for user calls */
4098  transformer pre,
4099  bool is_internal)
4100 {
4101  syntax sexpr = expression_syntax(expr);
4102  call c = syntax_call(sexpr);
4103  entity op = call_function(c);
4104  list args = call_arguments(c);
4106  int arity = gen_length(args);
4107 
4108  if(ENTITY_AMIN1_P(op)||ENTITY_DMIN1_P(op)||ENTITY_MIN_P(op)) {
4109  tf = generic_minmax_to_transformer(v, args, pre, true, is_internal);
4110  }
4111  if(ENTITY_C_MIN_P(op)) {
4112  args=CDR(args);
4113  --arity;
4114  tf = generic_minmax_to_transformer(v, args, pre, true, is_internal);
4115  }
4116  else if(ENTITY_AMAX1_P(op)||ENTITY_DMAX1_P(op)||ENTITY_MAX_P(op)) {
4117  tf = generic_minmax_to_transformer(v, args, pre, false, is_internal);
4118  }
4119  else if(value_code_p(entity_initial(op))
4121  /* Just in case some integer variables were modified by the function
4122  call, e.g. the count of its dynamic calls. */
4123  tf = user_function_call_to_transformer(v, expr, pre);
4124  }
4125  else {
4126  switch(arity) {
4127  case 0:
4128  /* tf = constant_to_transformer(v, call_function(syntax_call(srhs))); */
4129  tf = constant_to_transformer(v, expr);
4130  break;
4131  case 1:
4132  {
4133  expression e1 = EXPRESSION(CAR(args));
4134  tf = float_unary_operation_to_transformer(v, op, e1, pre, is_internal);
4135  break;
4136  }
4137  case 2:
4138  {
4139  expression e1 = EXPRESSION(CAR(args));
4140  expression e2 = EXPRESSION(CAR(CDR(args)));
4141  tf = float_binary_operation_to_transformer(v, op, e1, e2, pre, is_internal);
4142  break;
4143  }
4144  default:
4145  /* min, max,... */
4146  semantics_user_warning("Operator %s not analyzed\n", entity_name(op));
4147  }
4148  }
4149 
4150  return tf;
4151 }
4152 
4154  expression rhs,
4155  transformer pre,
4156  bool is_internal)
4157 {
4159  syntax srhs = expression_syntax(rhs);
4160 
4161  /* pre can be used if some integer variables with constant values have
4162  to be promoted to float. */
4163 
4164  /* pips_assert("Precondition is undefined", transformer_undefined_p(pre)); */
4165 
4166  switch(syntax_tag(srhs)) {
4167  case is_syntax_call:
4168  tf = float_call_expression_to_transformer(v, rhs, pre, is_internal);
4169  break;
4170  case is_syntax_reference:
4171  {
4172  //entity e = reference_variable(syntax_reference(srhs));
4173  // FI: some filtering needed if integer expressions should not
4174  // be exploited...
4175  reference r = syntax_reference(srhs);
4176  tf = generic_reference_to_transformer(v, r, pre, is_internal);
4177  break;
4178  }
4179  case is_syntax_range:
4180  pips_internal_error("Unexpected tag %d", syntax_tag(srhs));
4181  break;
4182  default:
4183  pips_internal_error("Illegal tag %d", syntax_tag(srhs));
4184  }
4185 
4186  return tf;
4187 }
4188 
4189 /* POINTER EXPRESSION */
4190 
4191 /**
4192  * Maybe move in ri-util/expression.c or in effect-util/pointer_values.c
4193  * \details search in an arithmetic pointer expression
4194  * if the pointer NULL is present
4195  * \param expr arithmetic expression to scan
4196  * \return true if expr contain NULL else false
4197  */
4199  syntax sexpr = expression_syntax(expr);
4200 
4201  switch (syntax_tag(sexpr)) {
4202  case is_syntax_reference:
4203  {
4204  reference rexpr = syntax_reference(sexpr);
4205  entity var = reference_variable(rexpr);
4206 
4208  basic b = variable_basic(type_variable(bctvar));
4209 
4210  if (basic_pointer_p(b)) {
4211  semantics_user_warning("TODO : Need to check if %s is indirectly NULL\n", expression_to_string(expr));
4212  // TODO : function that check if we have an expression/entity e=NULL in the transformer t
4213  // have to make projection of e and NULL (because can have : e=e1, e1=NULL)
4214  // is_entity/expression_equal_null_in_transformer(var/expr, pre)
4215  // Maybe we can use the info from points-to, we can want to analyze pointer without graph points-to, why?
4216  if (null_pointer_value_entity_p(var) || expression_null_p(expr)) //this test can be not sufficient
4217  return true;
4218  else
4219  return false;
4220  }
4221  else
4222  return false;
4223  break;
4224  }
4225  case is_syntax_call:
4226  {
4227  call cexpr = syntax_call(sexpr);
4228  entity func = call_function(cexpr);
4229 
4230  if (ENTITY_PLUS_P(func) || ENTITY_PLUS_C_P(func) ||
4231  ENTITY_MINUS_P(func) || ENTITY_MINUS_C_P(func)) {
4232  list args = call_arguments(cexpr);
4233  expression e1 = EXPRESSION(CAR(args));
4234  expression e2 = EXPRESSION(CAR(CDR(args)));
4235  pips_assert("2 args for arithmetic", CDR(CDR(args))==NIL);
4236 
4238  }
4239  else if (expression_constant_p(expr)) {
4240  return false;
4241  }
4242  else if(ENTITY_MULTIPLY_P(func)) {
4243  return false;
4244  }
4245  else {
4246  //this case normally never happen
4247  pips_internal_error("unexpected function call : %s\n", entity_name(func));
4248  }
4249  break;
4250  }
4251  default:
4252  //this case normally never happen
4253  pips_internal_error("unexpected syntaxe tag : %i\n", syntax_tag(sexpr));
4254  }
4255 
4256  //this case normally never happen
4257  pips_internal_error("error with expression : %s, syntax_tag : %i \n", expression_to_string(expr), syntax_tag(sexpr));
4258  return false;
4259 }
4260 
4261 /**
4262  * Maybe move in ri-util/expression.c or in effect-util/pointer_values.c
4263  * \details search in an arithmetic pointer expression
4264  * if the pointer NULL is present
4265  * \param expr arithmetic expression to scan
4266  * \return true if expr contain NULL else false
4267  */
4269  syntax sexpr = expression_syntax(expr);
4270 
4271  switch (syntax_tag(sexpr)) {
4272  case is_syntax_reference:
4273  {
4274  reference rexpr = syntax_reference(sexpr);
4275  entity var = reference_variable(rexpr);
4276 
4277  if (sizeof_value_entity_p(var)) {
4278  return true;
4279  }
4280  else
4281  return false;
4282  break;
4283  }
4284  case is_syntax_call:
4285  {
4286  call cexpr = syntax_call(sexpr);
4287  entity func = call_function(cexpr);
4288 
4289  if (ENTITY_MULTIPLY_P(func)) {
4290  list args = call_arguments(cexpr);
4291  expression e1 = EXPRESSION(CAR(args));
4292  expression e2 = EXPRESSION(CAR(CDR(args)));
4293  pips_assert("2 args for arithmetic", CDR(CDR(args))==NIL);
4294 
4296  }
4297  break;
4298  }
4299  default:
4300  return false;
4301  }
4302 
4303  //this case normally never happen
4304  pips_internal_error("error with expression : %s, syntax_tag : %i \n", expression_to_string(expr), syntax_tag(sexpr));
4305  return false;
4306 }
4307 
4308 /*
4309 static expression pointer_expression_to_pointer_expression_with_sizeof(expression exp) {
4310  expression result;
4311 
4312 
4313  return result;
4314 }
4315 */
4317  entity e, //entity to be affected (value not variable)
4318  entity op, //"Name" of the call function
4319  expression e1, //arg of the call function
4320  transformer pre,/* Predicate on current store assumed not modified by
4321  expr's side effects */
4322  bool is_internal)
4323 {
4325 
4326  //tf = generic_unary_operation_to_transformer(e, op, e1, pre, is_internal);
4327  // NL: can't call generic_unary_operation_to_transformer because of the case ABS
4328  // it's a copy of generic_unary_operation_to_transformer without the case ABS
4329  // add the case ADDRESS_OF
4330  if(ENTITY_DEREFERENCING_P(op)) {
4331  // tf = generic_unary_operation_to_transformer(e, op, e1, pre, is_internal);
4332  ; // Peformed at the end of the function
4333  }
4334  else if(ENTITY_UNARY_MINUS_P(op)) {
4335  tf = unary_minus_operation_to_transformer(e, e1, pre, is_internal);
4336  }
4339  syntax s1 = expression_syntax(e1);
4341 
4342  if(entity_has_values_p(v1)) {
4344  if(transformer_undefined_p(pre)) {
4345  tf = tfu;
4346  }
4347  else {
4348  /* FI: Oops, the precondition is lost here! See any_basic_update_to_transformer() */
4349  tf = transformer_combine(transformer_range(pre), tfu);
4350  free_transformer(tfu);
4351  }
4352  }
4353  }
4354  else if (ENTITY_ADDRESS_OF_P(op)) {
4355  syntax s1 = expression_syntax(e1);
4356 
4357  if (syntax_reference_p(s1)) {
4359  // entity v1 = reference_variable(r1);
4360 
4361  // create an entity for the address_of
4362  // add_address_of_value(r1, entity_type(e));
4363  // get the address_of entity
4364  // entity a1 = reference_to_address_of_value(r1);
4366  if(entity_undefined_p(a1)) {
4367  tf = transformer_identity(); // transformer_undefined might work too
4368  }
4369  else {
4370  // FI: is a1 usable ?
4371  if(entity_has_values_p(a1)) {
4372  // make the transformer for the equality (take from generic_reference_to_transformer)
4373  transformer tfr = simple_equality_to_transformer(e, a1, false);
4374  if(!transformer_undefined_p(pre)) {
4375  // FI: assume pre is a range
4376  tf = transformer_intersection(tfr, pre);
4377  }
4378  free_transformer(tfr);
4379  }
4380  else {
4381  tf = transformer_identity(); // transformer_undefined might work too
4382  }
4383  }
4384  }
4385  else if (syntax_call_p(s1)) {
4386  call c1 = syntax_call(s1);
4387  entity f1 = call_function(c1);
4388  // list args = call_arguments(c1);
4389 
4390  if (ENTITY_FIELD_P(f1)||ENTITY_POINT_TO_P(f1)) {
4391  //pips_internal_error("ADDRESS_OF for Struct : Not Implemented yet\n");
4392  tf = generic_unary_operation_to_transformer(e, op, e1, pre, is_internal);
4393  }
4394  else {
4395  //Normally this case never appear
4396  pips_internal_error("illegal expression_syntax, syntax_call_function\n syntax_tag : %i\n call_function : %s\n",
4397  syntax_tag(s1), entity_name(f1));
4398  }
4399  }
4400  else {
4401  //Normally this case never appear
4402  pips_internal_error("illegal expression_syntax, syntax_tag : %i",
4403  syntax_tag(s1));
4404  }
4405  }
4406 
4407  if(transformer_undefined_p(tf)) {
4408  // tf = points_to_unary_operation_to_transformer(e, op, e1, pre, is_internal, true);
4409  tf = generic_unary_operation_to_transformer(e, op, e1, pre, is_internal);
4410  }
4411 
4412  return tf;
4413 }
4414 
4416  entity e,
4417  expression expr,
4418  transformer pre,
4419  bool is_internal)
4420 {
4421  syntax sexpr = expression_syntax(expr);
4422  call c = syntax_call(sexpr);
4423  entity op = call_function(c);
4424  list args = call_arguments(c);
4425  expression e1 = EXPRESSION(CAR(args));
4426  expression e2 = EXPRESSION(CAR(CDR(args)));
4428 
4429  pips_debug(8, "Begin\n");
4430 
4431  if(ENTITY_PLUS_P(op) || ENTITY_MINUS_P(op)) {
4432  // can occur for arithmetic for pointer
4433  // e1+e2 or e1-e2, e1 and e2 not pointer
4434  tf = addition_operation_to_transformer(e, e1, e2, pre,
4435  ENTITY_PLUS_P(op),
4436  is_internal);
4437  }
4438  if(ENTITY_PLUS_C_P(op)) {
4439  // can occur for arithmetic for pointer
4440  // e1+e2, e1 or e2 pointer
4442  tf = transformer_empty();
4443  pips_user_error("Try to make arithmetic with NULL pointer : %s\n", expression_to_string(expr));
4444  }
4445  else {
4446  tf = addition_operation_to_transformer(e, e1, e2, pre,
4447  ENTITY_PLUS_C_P(op),
4448  is_internal);
4449  }
4450  }
4451  if(ENTITY_MINUS_C_P(op)) {
4452  // can occur for arithmetic for pointer
4453  // e1+e2, e1 or/and e2 pointer
4455  tf = transformer_empty();
4456  pips_user_error("Try to make arithmetic with NULL pointer : %s\n", expression_to_string(expr));
4457  }
4458  else {
4459  tf = addition_operation_to_transformer(e, e1, e2, pre,
4460  ENTITY_PLUS_C_P(op),
4461  is_internal);
4462  }
4463  }
4464  else if(ENTITY_MULTIPLY_P(op)) {
4465  // can occur for arithmetic for pointer
4466  // already multiply by the sizeof
4467  pips_debug(9, "ENTITY_MULTIPLY_P\n");
4469  tf = integer_multiply_to_transformer(e, e1, e2, pre, is_internal);
4470  pips_user_error("can't compute when sizeof already present in arithmetic yet : %s\n", expression_to_string(expr));
4471  }
4472  else {
4473  // compute the multiply with sizeof
4474  tf = expression_multiply_sizeof_to_transformer(e, expr, pre, is_internal);
4475  }
4476  }
4477  else if(ENTITY_PLUS_UPDATE_P(op) || ENTITY_MINUS_UPDATE_P(op)) {
4478  pips_user_error("UPDATE for rhs pointer not done yet : %s\n", expression_to_string(expr));
4479  //tf = update_operation_to_transformer(e, op, e1, e2, pre, is_internal);
4480  }
4481  else if(ENTITY_ASSIGN_P(op)) {
4482  semantics_user_warning("ASSIGN for rhs pointer not tested : %s\n", expression_to_string(expr));
4483  // Maybe need to be redesign like any_assign_to_transformer or assign_rhs_to_reflhs_to_transformer
4484  tf = assign_operation_to_transformer(e, e1, e2, pre);
4485  }
4486  else {
4487  semantics_user_warning("Operator %s not analyzed\n", entity_name(op));
4488  }
4489 
4490  pips_debug(8, "End with tf=%p\n", tf);
4491 
4492  return tf;
4493 }
4494 
4496  entity e, // value of the expression
4497  expression expr, /* needed to compute effects for user calls */
4498  transformer pre, /* Predicate on current store assumed not modified by
4499  expr's side effects */
4500  bool is_internal)
4501 {
4502  syntax sexpr = expression_syntax(expr);
4503  call c = syntax_call(sexpr);
4504  entity f = call_function(c);
4505  list args = call_arguments(c);
4507  int arity = gen_length(args);
4508 
4509  pips_debug(8, "Begin with precondition %p\n", pre);
4510  /* tests are organized to trap 0-ary user-defined functions as well as
4511  binary min and max */
4512 
4513  if(ENTITY_MIN0_P(f) || ENTITY_MIN_P(f)) {
4514  tf = min0_to_transformer(e, args, pre, is_internal);
4515  }
4516  else if(ENTITY_C_MIN_P(f)) {
4517  args=CDR(args);
4518  --arity;
4519  tf = min0_to_transformer(e,args,pre,is_internal);
4520  }
4521  else if(ENTITY_MAX0_P(f) || ENTITY_MAX_P(f)) {
4522  tf = max0_to_transformer(e, args, pre, is_internal);
4523  }
4524  else if(ENTITY_COMMA_P(f)) {
4525  // is_internal is dropped...
4526  tf = any_expressions_to_transformer(e, args, pre);
4527  }
4528  else if(ENTITY_CONDITIONAL_P(f)) {
4529  tf = any_conditional_to_transformer(e, args, pre);
4530  }
4531  else if(value_code_p(entity_initial(f)) &&
4533  tf = user_function_call_to_transformer(e, expr, pre);
4534  }
4535  else {
4536  switch(arity) {
4537  case 0:
4538  {
4539  // expr is a constant
4540  //tf = constant_to_transformer(e, expr);
4541  // occur for arithmetic for pointer
4542  // multiply the constant with he sizeof lhs
4543  // compute the multiply with sizeof
4544  tf = expression_multiply_sizeof_to_transformer(e, expr, pre, is_internal);
4545 
4546  break;
4547  }
4548  case 1:
4549  {
4550  expression e1 = EXPRESSION(CAR(args));
4551  tf = pointer_unary_operation_to_transformer(e, f, e1, pre, is_internal);
4552  break;
4553  }
4554  case 2:
4555  {
4556  //expression e1 = EXPRESSION(CAR(args));
4557  //expression e2 = EXPRESSION(CAR(CDR(args)));
4558  tf = pointer_binary_operation_to_transformer(e, expr, pre, is_internal);
4559  break;
4560  }
4561  default:
4562  semantics_user_warning("Operator %s not analyzed\n", entity_name(f));
4563  }
4564  }
4565 
4566  pips_debug(8, "End with tf=%p\n", tf);
4567 
4568  return tf;
4569 }
4570 
4571 /**
4572  * \details This function may return an undefined transformers if it fails to
4573  * capture the semantics of expr in the polyhedral framework.
4574  * cf any_expression_to_transformer which call it
4575  * \param v value of the expression
4576  * \param expr pointer expression
4577  * \param pre transformer, no side effect
4578  * \param is_internal ?? use in generic_reference_to_transformer
4579  * \return transformer with the pointer expression
4580  * or transformer_undefined if failed
4581  */
4583  expression expr,
4584  transformer pre,
4585  bool is_internal)
4586 {
4588  syntax sexpr = expression_syntax(expr);
4589 
4590  ifdebug(8) {
4591  pips_debug(8, "begin with precondition %p for expression: ", pre);
4592  print_expression(expr);
4593  }
4594 
4595  /* Assume: v is a value */
4596  switch (syntax_tag(sexpr)) {
4597  case is_syntax_call:
4598  {
4599  tf = transformer_undefined;
4600  tf = pointer_call_expression_to_transformer(v, expr, pre, is_internal);
4601  break;
4602  }
4603  case is_syntax_reference:
4604  {
4605  // pips_user_warning("reference for pointer analysis not be tested\n");
4606  // can occur for arithmetic for pointer
4607  reference rexpr = syntax_reference(sexpr);
4608 
4609  entity rvexpr = reference_variable(rexpr);
4610  type texpr = entity_type(rvexpr);
4611  type bctexpr = compute_basic_concrete_type(texpr);
4612  if(type_variable_p(bctexpr)) {
4613  variable vexpr = type_variable(bctexpr);
4614  if (!volatile_variable_p(vexpr)
4615  && ENDP(variable_dimensions(vexpr))
4616  && !basic_pointer_p(variable_basic(vexpr))) {
4617  // compute the multiply with sizeof
4618  tf = expression_multiply_sizeof_to_transformer(v, expr, pre, is_internal);
4619  }
4620  else
4621  tf = generic_reference_to_transformer(v, rexpr, pre, is_internal);
4622  }
4623  break;
4624  }
4625  case is_syntax_cast:
4626  {
4627  cast c = syntax_cast(sexpr);
4628  type ct = cast_type(c);
4629  expression cexp = cast_expression(c);
4630  type cexpt = expression_to_type(cexp);
4631 
4632  if (expression_null_p(expr)) {
4633  // make the transformer for the equality (take from generic_reference_to_transformer)
4635  if(!transformer_undefined_p(pre)) {
4636  // FI: assume pre is a range
4637  tf = transformer_intersection(tfr, pre);
4638  }
4639  free_transformer(tfr);
4640  } else {
4641  semantics_user_warning("Cast for pointer analysis not tested "
4642  "(except for NULL pointer).\n");
4643  if (type_equal_p(ct, cexpt))
4644  tf = pointer_expression_to_transformer(v, cexp, pre, is_internal);
4645  else
4646  tf = transformer_undefined;
4647  //pips_internal_error("Illegal tag %d", syntax_tag(sexpr));
4648  free_type(cexpt);
4649  }
4650  break;
4651  }
4652  default:
4653  tf = transformer_undefined;
4654  //pips_internal_error("Illegal tag %d", syntax_tag(sexpr));
4655  }
4656 
4657  pips_debug(8, "end with tf=%p\n", tf);
4658 
4659  return tf;
4660 }
4661 
4662 
4663 ␌
4664 /* Assimilate enum and logical to int (used when they appear in logical
4665  * operations)
4666  *
4667  * FI: Might be useful quite often in semantics... but forces the
4668  * programmer to use tags of basic instead of basic variables.
4669  */
4671 {
4672  int t = basic_tag(b);
4673 
4674  if(t==is_basic_derived) {
4675  entity d = basic_derived(b);
4676  type dt = entity_type(d);
4677  if(type_enum_p(dt))
4678  t = is_basic_int;
4679  }
4680  else if(t==is_basic_logical)
4681  t = is_basic_int;
4682 
4683  return t;
4684 }
4685 
4687  transformer pre, /* precondition */
4688  entity op,
4689  expression e1,
4690  expression e2,
4692  bool veracity, /* the relation is true or not */
4693  bool upwards) /* compute transformer or precondition */
4694 {
4697  int t1 = semantics_basic_tag(b1);
4698  int t2 = semantics_basic_tag(b2);
4699 
4700  pips_debug(8, "begin %s with pre=%p\n",
4701  upwards? "upwards" : "downwards", pre);
4702 
4703  /* This is not satisfactory: when going upwards you might nevertheless
4704  benefit from some precondition information. But you would then need
4705  to pass two transformers as argument: a context transformer and a
4706  to-be-modified transformer */
4707 
4708  /* context = upwards? transformer_undefined : pre; */
4709  /* context = transformer_range(pre); */
4710 
4711  if( (t1==t2)
4712  || (t1==is_basic_int && t2==is_basic_string)
4713  || (t2==is_basic_int && t1==is_basic_string) ) {
4714 
4715  switch(t1) {
4716  case is_basic_logical:
4717  /* Logical are represented by integer values*/
4718  case is_basic_float:
4719  /* PIPS does not represent negative constants: call to unary_minus */
4720  case is_basic_complex:
4721  /* PIPS does not represent complex constants: call to CMPLX */
4722  case is_basic_string:
4723  /* Only constant string are processed */
4724  case is_basic_pointer:
4725  /* Pointer analysis */
4726  case is_basic_int:
4727  {
4728  /* This is not correct if side effects occur in e1 or e2 */
4729  /* This is very complicated to add constraints from tf1, tf2 and
4730  rel in pre! */
4734  /* tf1 may modify the initial context. See w10.f */
4736  : transformer_apply(tf1, context);
4737  transformer ncontext = transformer_range(pcontext);
4738  transformer tf2 = safe_any_expression_to_transformer(tmp2, e2, ncontext, true);
4739  // FI: not precise because the context is not taken into
4740  // account when non-convex information is available,
4741  // non-convex information that could be convex within the
4742  // context. But see below.
4743  transformer rel = relation_to_transformer(op, tmp1, tmp2, veracity);
4746 
4747  free_transformer(pcontext);
4748  free_transformer(ncontext);
4749 
4750  /* tf1 disappears into cond */
4751  cond = transformer_safe_combine_with_warnings(tf1, tf2);
4752 
4754  /* try to break rel it into two convex components */
4755  if((ENTITY_NON_EQUAL_P(op) && veracity)
4756  || (ENTITY_EQUAL_P(op) && !veracity)) {
4759  transformer rel1 = relation_to_transformer(lt, tmp1, tmp2, true);
4760  transformer rel2 = relation_to_transformer(gt, tmp1, tmp2, true);
4761  transformer full_cond1 = transformer_safe_image_intersection(cond, rel1);
4762  transformer full_cond2 = transformer_safe_image_intersection(cond, rel2);
4763  /* pre disappears into newpre2 */
4764  transformer newpre1 = transformer_combine(transformer_dup(pre), full_cond1);
4765  transformer newpre2 = transformer_combine(pre, full_cond2);
4766 
4767  free_transformer(rel1);
4768  free_transformer(rel2);
4769 
4770  newpre = transformer_convex_hull(newpre1, newpre2);
4771 
4772  free_transformer(full_cond1);
4773  free_transformer(full_cond2);
4774  free_transformer(newpre1);
4775  free_transformer(newpre2);
4776  }
4777  }
4778  else if (!transformer_undefined_p(cond)){
4779  transformer full_cond = transformer_safe_image_intersection(cond, rel);
4780  /* pre disappears into newpre */
4781  newpre = transformer_combine(pre, full_cond);
4782  free_transformer(full_cond);
4783  }
4784  else {
4785  /* newpre stays undefined or newpre is pre*/
4786  newpre = pre;
4787  }
4788 
4789  transformer_free(cond);
4790  pre = newpre;
4791 
4792  pips_assert("Pre is still consistent with tf1 and tf2 and rel",
4794 
4795  /* free_transformer(tf1); already gone */
4796  free_transformer(tf2);
4797  free_transformer(rel);
4798  break;
4799  }
4800  case is_basic_overloaded:
4801  pips_internal_error("illegal overloaded type for operator %s",
4802  entity_name(op));
4803  break;
4804  case is_basic_bit:
4805  // Do not emit the same message during the second analysis of
4806  // the condition
4807  if(veracity)
4808  semantics_user_warning("bit type not analyzed for operator %s\n",
4809  entity_name(op));
4810  break;
4811 // case is_basic_pointer:
4812 // if(veracity)
4813 // semantics_user_warning("pointer type not analyzed for operator %s\n",
4814 // entity_name(op));
4815 // break;
4816  case is_basic_derived:
4817  /* Nothing to be done with struct and union */
4818  break;
4819  case is_basic_typedef:
4820  pips_internal_error("typedef should ne converted to concrete types for operator %s",
4821  entity_name(op));
4822  break;
4823  default:
4824  pips_internal_error("unknown basic b=%d", basic_tag(b1));
4825  }
4826  }
4827 
4828  free_basic(b1);
4829  free_basic(b2);
4830 
4831  pre = transformer_normalize(pre, 2);
4832 
4833  /* pre may be unchanged when no information is derived */
4834  pips_debug(8, "end with pre=%p\n", pre);
4835 
4836  return pre;
4837 }
4838 ␌
4839 /* The value of the expression is irrelevant, but its sub-expressions
4840  * may generate a transformer.
4841  *
4842  * FI: use Newgen to reimplement this using abstract transformers to
4843  * simplify the recursion ?
4844  */
4846  expression e,
4847  transformer p,
4848  bool is_internal __attribute__ ((unused)))
4849 {
4851  syntax s = expression_syntax(e);
4852  switch(syntax_tag(s)) {
4853  case is_syntax_reference: {
4854  reference r = syntax_reference(s);
4855  list el = reference_indices(r);
4856  //tf = any_expressions_side_effects_to_transformer(el, p, is_internal);
4857  tf = expressions_to_transformer(el, p);
4858  };
4859  break;
4860  case is_syntax_range: {
4861  pips_internal_error("Not implemented yet.\n");
4862  break;
4863  };
4864  case is_syntax_call: {
4865  call c = syntax_call(s);
4866  list el = call_arguments(c);
4867  tf = any_expressions_side_effects_to_transformer(el, p, is_internal);
4868  break;
4869  };
4870  case is_syntax_cast: {
4871  cast c = syntax_cast(s);
4872  expression ce = cast_expression(c);
4873  tf = any_expression_side_effects_to_transformer(ce, p, is_internal);
4874  break;
4875  };
4880  tf = any_expression_side_effects_to_transformer(soee, p, is_internal);
4881  }
4882  break;
4883  };
4884  case is_syntax_subscript: {
4885  subscript ss = syntax_subscript(s);
4886  expression ae = subscript_array(ss);
4887  list sel = subscript_indices(ss);
4888  tf =
4889  any_expression_side_effects_to_transformer(ae, p, is_internal);
4890  transformer etf =
4891  any_expressions_side_effects_to_transformer(sel, p, is_internal);
4892  tf = transformer_combine(tf, etf);
4893  free_transformer(etf);
4894  break;
4895  };
4896  case is_syntax_application: {
4899  list al = application_arguments(a);
4900  tf = any_expression_side_effects_to_transformer(fe, p, is_internal);
4901  transformer etf =
4902  any_expressions_side_effects_to_transformer(al, p, is_internal);
4903  tf = transformer_combine(tf, etf);
4904  free_transformer(etf);
4905  break;
4906  };
4907  case is_syntax_va_arg: {
4908  // FI: what could be useful ? Explore the sizeofexpressions ?
4909  break;
4910  };
4911  default:
4912  pips_internal_error("Unexpected or unimplemented tad=%d", syntax_tag(s));
4913  break;
4914  }
4915  return tf;
4916 }
4917 
4918 /* same as any_expression_side_effects_to_transformer() but for a list
4919  * of expressions
4920  */
4922 {
4924  FOREACH(EXPRESSION, e, el) {
4925  transformer etf =
4926  any_expression_side_effects_to_transformer(e, p, is_internal);
4927  if(transformer_undefined_p(tf))
4928  tf = etf;
4929  else {
4930  tf = transformer_combine(tf, etf);
4931  free_transformer(etf);
4932  }
4933  }
4934  return tf;
4935 }
4936 
4937 /* Same as any_expression_side_effects_to_transformer() but effects
4938  * are used to always generate a transformer.
4939  *
4940  * FI: I do not know how effects should be used. It might be useful to
4941  * allow special transformers using location abstraction to simplify
4942  * the recurrence. Currently, effects are used or not. It might be
4943  * necessary to use only some of them at a given time in the
4944  * evaluation process as variables can be assigned almost anywhere in
4945  * C.
4946  */
4948  expression e,
4949  transformer p,
4950  bool is_internal)
4951 {
4952  transformer tf =
4953  any_expression_side_effects_to_transformer(e, p, is_internal);
4954  if(transformer_undefined_p(tf)) {
4956  }
4957 
4958  return tf;
4959 }
4960 ␌
4961 /* A set of functions to compute the transformer associated to an
4962  expression evaluated in a given context.
4963 
4964  The choices are:
4965 
4966  1. Do I need the value of the expression? It seems strange but in
4967  some cases, the expression value is discarded. See for instance the C for construct.
4968 
4969  Keyword: "any" implies that the expression value is needed
4970 
4971  2. In case of failure, do I need an approximate transformer based
4972  on memory effects or an undefined transformer because I want to try
4973  something else?
4974 
4975  Keyword: "safe" implies that effects are used and that no undefined
4976  transformer is returned.
4977 
4978  3. In case of interprocedural call, am I ready to fail? This might
4979  be useful for the libraries "control" and "effects", but is not
4980  implemented yet.
4981 
4982  Suggested keyword: "light"
4983 
4984  4. Conditional expressions require specific treatment because the
4985  bool analysis is not well linked to the integer analysis and
4986  because C uses implicit conditions: if(n) means if(n!=0).
4987 
4988  5. Expression lists are a special case of expression.
4989  */
4990 
4991 /* This function may return an undefined transformers if it fails to
4992  capture the semantics of expr in the polyhedral framework. */
4994  entity v, // value of the expression
4995  expression expr,
4996  transformer pre,
4997  bool is_internal)
4998 {
5000  basic be = basic_of_expression(expr);
5002 
5003  if(basic_typedef_p(be)) {
5004  entity te = basic_typedef(be);
5005  type nte = ultimate_type(entity_type(te));
5006 
5007  pips_assert("nte is of type variable", type_variable_p(nte));
5008 
5009  /* Should basic of expression take care of this? */
5010  pips_debug(8, "Fix basic be\n");
5011 
5012  free_basic(be);
5014  }
5015 
5016  ifdebug(8) {
5017  pips_debug(8, "begin for entity %s of type %s and %s expression ",
5018  entity_local_name(v),
5019  basic_to_string(bv), basic_to_string(be));
5020  print_expression(expr);
5021  }
5022 
5023  /* Assume v is a value */
5024  if( (basic_tag(bv)==basic_tag(be))
5025  || (basic_float_p(bv) && basic_int_p(be))
5026  || (basic_derived_p(bv) && basic_int_p(be))
5027  || (basic_derived_p(be) && basic_int_p(bv))
5028  || (basic_logical_p(bv) && basic_int_p(be))
5029  || (basic_logical_p(be) && basic_int_p(bv))
5030  || (basic_pointer_p(bv) && basic_int_p(be))) {
5031  switch(basic_tag(be)) {
5032  case is_basic_int:
5033  if(integer_analyzed_p()) {
5034  if(basic_int_p(bv)) {
5035  tf = integer_expression_to_transformer(v, expr, pre, is_internal);
5036  }
5037  else if(basic_derived_p(bv)) {
5038  /* If we are here, it should be an enum type... */
5039  tf = integer_expression_to_transformer(v, expr, pre, is_internal);
5040  }
5041  else if(basic_logical_p(bv)) {
5042  tf = logical_expression_to_transformer(v, expr, pre, is_internal);
5043  }
5044  else if(basic_pointer_p(bv)) {
5045  //tf = integer_expression_to_transformer(v, expr, pre, is_internal);
5046  // arithmetic for pointer
5047  if(pointer_analyzed_p())
5048  tf = pointer_expression_to_transformer(v, expr, pre, is_internal);
5049  }
5050  else {
5051  semantics_user_warning("Integer expression assigned to float value\n"
5052  "Apply PIPS type checker for better results\n");
5053  /* Constants, at least, could be typed coerced */
5054  /* Redundant with explicit type coercion also available in PIPS */
5055  /* To be done later */
5056  }
5057  }
5058  break;
5059  case is_basic_logical:
5060  if(basic_logical_p(bv) && boolean_analyzed_p())
5061  tf = logical_expression_to_transformer(v, expr, pre, is_internal);
5062  else if(basic_int_p(bv)) { // We should check that integers are analyzed...
5063  tf = integer_expression_to_transformer(v, expr, pre, is_internal);
5064  }
5065  break;
5066  case is_basic_float:
5067  /* PIPS does not represent negative constants: call to unary_minus */
5068  if(float_analyzed_p())
5069  tf = float_expression_to_transformer(v, expr, pre, is_internal);
5070  break;
5071  case is_basic_pointer:
5072  if(pointer_analyzed_p())
5073  tf = pointer_expression_to_transformer(v, expr, pre, is_internal);
5074  break;
5075  case is_basic_complex:
5076  /* PIPS does not represent complex constants: call to CMPLX */
5077  break;
5078  case is_basic_string:
5079  /* Only constant string are processed */
5080  if(string_analyzed_p())
5081  tf = string_expression_to_transformer(v, expr);
5082  break;
5083  case is_basic_overloaded: {
5084  /* The overloading is supposed to have been lifted by
5085  basic_of_expression() */
5087  tf = transformer_identity();
5088  else
5089  pips_internal_error("illegal overloaded type for an expression");
5090  break;
5091  }
5092  case is_basic_derived: {
5093  entity de = basic_derived(be);
5094  type det = ultimate_type(entity_type(de));
5095  if(type_enum_p(det)) {
5096  /* enum type are analyzed like int */
5097  tf = integer_expression_to_transformer(v, expr, pre, is_internal);
5098  }
5099  else {
5100  pips_internal_error("entities of type \"derived\" that are not \"enum\" cannot be analyzed");
5101  }
5102  break;
5103  }
5104  case is_basic_typedef:
5105  pips_internal_error("entities of type \"typedef\" cannot be analyzed");
5106  break;
5107  default:
5108  pips_internal_error("unknown basic b=%d", basic_tag(be));
5109  }
5110  }
5111  else {
5112  if(!basic_overloaded_p(be)) {
5113  semantics_user_warning("Implicit type coercion between variable \"%s\" of type \"%s\" and "
5114  "expression \"%s\" of type \"%s\" may reduce semantic analysis accuracy.\n"
5115  "You might apply 'type_checker' to explicit all type coercions.\n",
5116  entity_user_name(v),
5117  basic_to_string(bv),
5118  expression_to_string(expr),
5119  basic_to_string(be));
5120  }
5121  else if(!unbounded_expression_p(expr)) {
5122  /* This function is called from the region analysis, with
5123  * extended expressions such as "*", the unbounded
5124  * expression.
5125  */
5127  "expression \"%s\" with overloaded type may reduce semantic analysis accuracy for variable \"%s\" of type \"%s\".\n"
5128  "You might apply 'type_checker' to explicit all type coercions.\n",
5129  expression_to_string(expr),
5130  entity_user_name(v),
5131  basic_to_string(bv));
5132  }
5133  /* It might be interesting to go further in case the comma operator is used */
5134  if(comma_expression_p(expr)) {
5135  call c = syntax_call(expression_syntax(expr));
5136  list expr_l = call_arguments(c);
5137 
5138  /* No need to link the returned value as it must be cast to the
5139  proper type. */
5140  tf = expressions_to_transformer(expr_l, pre);
5141  }
5142  }
5143 
5144  /* tf may be transformer_undefined when no information is derived */
5145  ifdebug(1) {
5146  if(!transformer_undefined_p(pre))
5147  pips_assert("No obvious aliasing between tf and pre", tf!=pre);
5148  }
5149  pips_debug(8, "end with tf=%p\n", tf);
5150 
5151  return tf;
5152 }
5153 
5154 /* Always return a usable transformer. Use effects if no better
5155  transformer can be found */
5157  entity v, // value of the expression
5158  expression expr,
5159  transformer pre,
5160  bool is_internal)
5161 {
5164  transformer tf = any_expression_to_transformer(v, expr, npre, is_internal);
5165 
5166  if(transformer_undefined_p(tf)) {
5167  //list el = expression_to_proper_effects(expr);
5169  tf = effects_to_transformer(el);
5170 
5171  /*
5172  pips_assert("effect references are protected by persistant",
5173  effect_list_can_be_safely_full_freed_p(el));*/
5174 
5176 
5177  gen_full_free_list(el);
5178  }
5179  free_transformer(npre);
5180 
5181  return tf;
5182 }
5183 
5184 /* Just to capture side effects as the returned value is
5185  * ignored. Example: "(void) inc(&i);".
5186  *
5187  * Or to capture the return of a struct, which cannot be expressed
5188  * with an atomic return value.
5189  */
5191  expression exp,
5192  transformer pre,
5193  list el)
5194 {
5196  //entity tmpv = entity_undefined;
5198 
5199  if(type_void_p(et)) {
5200  /* FI: I assume this implies a cast to (void) but I'm wrong for
5201  any call to a void function. */
5202  syntax s_exp = expression_syntax(exp);
5203 
5204  if(syntax_cast_p(s_exp)) {
5205  expression sub_exp = cast_expression(syntax_cast(s_exp));
5206  type cet = expression_to_type(sub_exp);
5207 
5208  if(analyzed_type_p(cet)) {
5210 
5211  /* FI: I do not remember the meaning of the last parameter */
5212  // it's use in generic_reference_to_transformer
5213  tf = any_expression_to_transformer(tmpv, sub_exp, pre, false);
5214  }
5215  free_type(cet);
5216  }
5217  else if(syntax_call_p(s_exp)) {
5218  /* Must be a call to a void function */
5219  call c = syntax_call(s_exp);
5220  //list el = expression_to_proper_effects(exp);;
5222  tf = call_to_transformer(c, pre, el);
5223  }
5224  else {
5225  /* Wait till it happpens... */
5226  pips_internal_error("This case is not handled yet");
5227  }
5228  }
5229  else if(analyzed_type_p(et)) {
5231  /* FI: is_internal_p has an impact on renaming in
5232  simple_affine_to_transformer(). */
5233  tf = any_expression_to_transformer(tmpv, exp, pre, true);
5234  }
5235  else {
5236  // FI: we should go down recursively anyway because of casts and
5237  // side effects in C...
5241  }
5242  else if(expression_call_p(exp)) {
5243  call c = expression_call(exp);
5244  entity f = call_function(c);
5245  /* FI: there may be (many) other exceptions with intrinsics...
5246  *
5247  * Fortran intrinsics, such as IOs, are not taken into account
5248  * because these code should not be executed for Fortran code.
5249  */
5252  pre);
5253  }
5254  else if (entity_module_p(f)){
5255  list al = call_arguments(c);
5256  tf = user_call_to_transformer(f, al, pre, el);
5257  }
5258  else
5259  // FI: I am not pleased with this at all, but no time to think
5261  }
5262  else if(expression_cast_p(exp)) {
5263  cast c = expression_cast(exp);
5264  expression sub_exp = cast_expression(c);
5265  tf = safe_expression_to_transformer(sub_exp, pre);
5266  }
5270  expression sub_exp = sizeofexpression_expression(soe);
5271  tf = safe_expression_to_transformer(sub_exp, pre);
5272  }
5273  }
5274  else if(expression_subscript_p(exp)) {
5278  transformer tf2
5280  tf = transformer_combine(tf1, tf2);
5281  free_transformer(tf2); // tf1 is exported in tf
5282  }
5283  else if(expression_application_p(exp)) {
5285  expression func = application_function(a);
5287  transformer tf2
5289  tf = transformer_combine(tf1, tf2);
5290  free_transformer(tf2); // tf1 is exported in tf
5291  }
5292  // FI: Many other possible cases: range, sizeofexpression, subscript,
5293  // application, va_arg
5294  }
5295 
5296  /* If everything else has failed. */
5297  if(transformer_undefined_p(tf))
5298  tf = effects_to_transformer(el);
5299  else
5301 
5302  free_type(et);
5303 
5304  return tf;
5305 }
5306 
5308 {
5309  /* This simple function does not take points-to information into
5310  account. Furthermore, precise points-to information is not
5311  available when side effects occur as in comma expressions.
5312 
5313  FI: I do not see a simple way out. I can try to fix partly the
5314  problem in statement_to_transformer where the effects are
5315  known... Or I can play safer and use an effect function that
5316  replaces dereferencements by anywhere effects.
5317 
5318  See anywhere03.c as an example of the issue.
5319  */
5321  // To be careful with extended expressions generated by points-to information
5324  entity v = reference_variable(r);
5325  if(entity_field_p(v)) { // s[var1], not effect no a constant
5326  tf = transformer_identity();
5327  }
5328  }
5329 
5330  if(transformer_undefined_p(tf)) {
5331  //list el = expression_to_proper_effects(exp);
5333  tf = expression_to_transformer(exp, pre, el);
5334 
5335  gen_full_free_list(el);
5336  }
5337 
5338  return tf;
5339 }
5340 
5341 /* To capture side effects and to add C twist for numerical
5342  * conditions. Argument pre may be undefined.
5343  *
5344  * Beware of tricky conditions using the comma or the conditional
5345  * operator, although they should be handled as the default case,
5346  * using effects.
5347  */
5349  transformer pre,
5350  bool veracity)
5351 {
5353 
5354  if(expression_cast_p(cond)) {
5356  tf = condition_to_transformer(nc, pre, veracity);
5357  }
5358  else {
5359  //list el = expression_to_proper_effects(cond);
5361  transformer safe_pre = transformer_undefined_p(pre)?
5363  transformer_range(pre);
5364  basic eb = basic_of_expression(cond);
5365  bool relation_p = false;
5366  /* upwards should be set to false when computing preconditions (but
5367  we have no way to know) or when computing tramsformers in
5368  context. And set to true in other cases. upwards is a way to gain
5369  execution time at the expense of precision. This speed/accuracy
5370  tradeoff has evolved with CPU technology. */
5371  bool upwards = false;
5372  expression tcond = cond; // By default; not true for the comma operations
5373 
5374  /* If a comma operator is used, the test is the last expression */
5375  /* FI: quid of a conditional operator? e.g. "x>0?1<m:1<n" */
5376  /* FI: quid of assignment operator? e.g. "i = j = k = 1" */
5377  /* FI: we probably need a function tcond = expression_to_condition(cond) */
5378  if(expression_call_p(cond)) {
5379  call c = syntax_call(expression_syntax(cond));
5380  entity op = call_function(c);
5381  if(ENTITY_COMMA_P(op)) {
5382  list args = call_arguments(c);
5383  tcond = EXPRESSION(CAR(gen_last(args)));
5384  tf = safe_expression_to_transformer(cond, pre);
5385  }
5386  }
5387  if(transformer_undefined_p(tf)) {
5388  tf = transformer_identity();
5389  }
5390 
5391  /* C comparison operators return an integer value */
5392  if(!basic_logical_p(eb) && expression_call_p(tcond)) {
5394 
5395  relation_p = ENTITY_LOGICAL_OPERATOR_P(op);
5396  //relation_p = ENTITY_RELATIONAL_OPERATOR_P(op);
5397  }
5398 
5399  if(basic_logical_p(eb)) {
5400  // entity tmpv = make_local_temporary_value_entity_with_basic(eb);
5401  //tf = logical_expression_to_transformer(tmpv, cond, safe_pre, true);
5402  //tf = transformer_add_condition_information_updown
5403  // (transformer_identity(), cond, safe_pre, veracity, upwards);
5404  /* FI: not good when side effects in cond */
5405  //tf = transformer_add_condition_information_updown
5406  // (copy_transformer(safe_pre), cond, safe_pre, veracity, upwards);
5408  (tf, tcond, safe_pre, veracity, upwards);
5409  tf = transformer_apply(ctf, safe_pre);
5410  free_transformer(ctf);
5411  }
5412  else if(relation_p) {
5413  //tf = transformer_add_condition_information_updown
5414  // (transformer_identity(), cond, safe_pre, veracity, upwards);
5415  //tf = transformer_add_condition_information_updown
5416  // (copy_transformer(safe_pre), cond, safe_pre, veracity, upwards);
5417  /* In case, there are side-effects in the condition. This is very
5418  unlikely for standard code and should be simplified with a
5419  test to transformer_identity_p(tf) */
5420  transformer new_pre = transformer_apply(tf, safe_pre);
5421  transformer new_pre_r = transformer_range(new_pre);
5422  new_pre_r = transformer_normalize(new_pre_r, 2);
5424  (transformer_identity(), tcond, new_pre_r, veracity, upwards);
5426  ctf = transformer_normalize(ctf, 2);
5427  tf = transformer_combine(tf, ctf);
5428  free_transformer(ctf);
5429  free_transformer(new_pre);
5430  free_transformer(new_pre_r);
5431  }
5432  else {
5433  /* Make sure you can handle this kind of variable.
5434 
5435  This test is added for Semantics-New/transformer01.c which
5436  tests a pointer. The underlying bug may still be there when
5437  pointers are analyzed by PIPS.
5438  */
5439  if(analyzed_basic_p(eb)) {
5441  transformer ctf = safe_any_expression_to_transformer(tmpv, tcond, safe_pre, true);
5442  tf = transformer_combine(tf, ctf);
5443  if(veracity) {
5444  /* tmpv != 0 */
5447 
5448  ifdebug(8) {
5449  fprintf(stderr, "tf_plus %p:\n", tf_plus);
5450  dump_transformer(tf_plus);
5451  fprintf(stderr, "tf_minus %p:\n", tf_minus);
5452  dump_transformer(tf_minus);
5453  }
5454 
5455  free_transformer(tf);
5456  tf = transformer_convex_hull(tf_plus, tf_minus);
5457  free_transformer(tf_plus);
5458  free_transformer(tf_minus);
5459  }
5460  else {
5461  /* tmpv==0 */
5462  tf = transformer_add_sign_information(tf, tmpv, 0);
5463  }
5464  }
5465  }
5466 
5467  if(transformer_undefined_p(tf))
5468  tf = effects_to_transformer(el);
5469  else {
5470  /* Not yet? We may be in a = c? x : y; or in e1, e2,...; Does it matter? */
5472  //reset_temporary_value_counter();
5473  }
5474  /* May be dangerous if this routine is called internally to another
5475  routine using temporary variables... */
5476  /* reset_temporary_value_counter(); */
5477 
5478  gen_full_free_list(el);
5479  free_basic(eb);
5480  free_transformer(safe_pre);
5481  }
5482 
5483  return tf;
5484 }
5485 ␌
5486 /* FI: not too smart to start with the special case with no value
5487  returned, just side-effects... */
5489  expression te,
5490  expression fe,
5491  transformer pre,
5492  list ef)
5493 {
5495  transformer ttf = condition_to_transformer(cond, pre, true);
5496  transformer t_pre = transformer_apply(ttf, pre);
5497  transformer t_pre_r = transformer_range(t_pre);
5498  transformer tet = safe_expression_to_transformer(te, t_pre_r);
5499  transformer ftf = condition_to_transformer(cond, pre, false);
5500  transformer f_pre = transformer_apply(ftf, pre);
5501  transformer f_pre_r = transformer_range(f_pre);
5502  transformer fet = safe_expression_to_transformer(fe, f_pre_r);
5503 
5504  ttf = transformer_combine(ttf, tet);
5505  ftf = transformer_combine(ftf, fet);
5506  tf = transformer_convex_hull(ttf, ftf);
5507 
5508  free_transformer(ttf);
5509  free_transformer(ftf);
5510  free_transformer(tet);
5511  free_transformer(fet);
5512  free_transformer(t_pre_r);
5513  free_transformer(f_pre_r);
5514  free_transformer(t_pre);
5515  free_transformer(f_pre);
5516 
5517  if(transformer_undefined_p(tf))
5518  tf = effects_to_transformer(ef);
5519  return tf;
5520 }
5521 
5522 /* Take care of the returned value. About a cut-and-paste of previous
5523  function, conditional_to_transformer(). */
5525  list args,
5526  transformer pre)
5527 {
5528  expression cond = EXPRESSION(CAR(args));
5529  expression te = EXPRESSION(CAR(CDR(args)));
5530  expression fe = EXPRESSION(CAR(CDR(CDR(args))));
5532  transformer ttf = condition_to_transformer(cond, pre, true);
5533  transformer t_pre = transformer_apply(ttf, pre);
5534  transformer t_pre_r = transformer_range(t_pre);
5535  transformer tet = safe_any_expression_to_transformer(v, te, t_pre_r, true);
5536  transformer ftf = condition_to_transformer(cond, pre, false);
5537  transformer f_pre = transformer_apply(ftf, pre);
5538  transformer f_pre_r = transformer_range(f_pre);
5539  transformer fet = safe_any_expression_to_transformer(v, fe, f_pre_r, true);
5540 
5541  ttf = transformer_combine(ttf, tet);
5542  ftf = transformer_combine(ftf, fet);
5543  tf = transformer_convex_hull(ttf, ftf);
5544 
5545  free_transformer(ttf);
5546  free_transformer(ftf);
5547  free_transformer(tet);
5548  free_transformer(fet);
5549  free_transformer(t_pre_r);
5550  free_transformer(f_pre_r);
5551  free_transformer(t_pre);
5552  free_transformer(f_pre);
5553 
5554  //if(transformer_undefined_p(tf))
5555  // tf = effects_to_transformer(ef);
5556  return tf;
5557 }
5558 
5559 /* returns the transformer associated to a C logical not, !, applied
5560  * to an integer argument, when meaningful, and transformer_undefined
5561  * otherwise. Effects must be used at a higher level to fall back on a
5562  * legal transformer.
5563  *
5564  * @param v is the value associated to the expression
5565  *
5566  * @param args is assumed to have only one expression element of type
5567  * int or enum negated by !
5568  *
5569  * @param pre is the current precondition
5570  */
5572  list args,
5573  transformer pre)
5574 {
5575  expression le = EXPRESSION(CAR(args));
5576  //basic be = basic_of_expression(le);
5578 
5579  //if(basic_int_p(be)) {
5581  tf = safe_any_expression_to_transformer(tmp_v, le, pre, true);
5582  transformer tfr = transformer_range(tf);
5583  intptr_t lb, ub;
5584 
5585  if(precondition_minmax_of_value(tmp_v, tfr, &lb, &ub)) {
5586  if(lb==ub && lb==0)
5588  else if(lb>0 || ub<0)
5590  else {
5593  }
5594  }
5595  else {
5598  }
5599  free_transformer(tfr);
5600  // }
5601 
5602  //free_basic(be);
5603 
5604  return tf;
5605 }
5606 
5607 /* returns the transformer associated to a C bitwise xor, ^, applied
5608  * to two integer argument, when meaningful, and transformer_undefined
5609  * otherwise. Effects must be used at a higher level to fall back on a
5610  * legal transformer.
5611  *
5612  * @param v is the value associated to the expression
5613  *
5614  * @param args is assumed to have only one expression element of type
5615  * int negated by !
5616  *
5617  * @param pre is the current precondition
5618  */
5620  list args,
5621  transformer pre)
5622 {
5623  /* Something can be done when both arguments have values in [0,1],
5624  when both arguments have known numerical values, when both
5625  arguments have the same value,... However, all this
5626  tests imply lots time consuming projections for a limited
5627  result... Unless somebody uses XOR to flip-flop between
5628  arrays... for instance to bother Sven Verdoolaege:-). A logical
5629  not might be more useful for this:-). */
5630  expression le1 = EXPRESSION(CAR(args));
5631  //basic be1 = basic_of_expression(le1);
5632  expression le2 = EXPRESSION(CAR(CDR(args)));
5633  //basic be2 = basic_of_expression(le2);
5635 
5636  //if(basic_int_p(be1) && basic_int_p(be2)) {
5638  // FI: Even with the "in context" property, the precondition is
5639  // not integrated into the transformer...
5640  transformer tf1 = safe_any_expression_to_transformer(tmp_v1, le1, pre, true);
5641  //transformer tfr1 = transformer_range(tf1);
5642  transformer tfr1 = transformer_apply(tf1, pre);
5643  intptr_t lb1, ub1;
5645  transformer tf2 = safe_any_expression_to_transformer(tmp_v2, le2, pre, true);
5646  // transformer tfr2 = transformer_range(tf2);
5647  transformer tfr2 = transformer_apply(tf2, pre);
5648  intptr_t lb2, ub2;
5649 
5650  if(precondition_minmax_of_value(tmp_v1, tfr1, &lb1, &ub1)
5651  && precondition_minmax_of_value(tmp_v2, tfr2, &lb2, &ub2)) {
5652  if(lb1==ub1 && lb2==ub2) {
5653  /* The two values are know at compile time */
5654  tf = transformer_identity();
5655  tf = transformer_add_equality_with_integer_constant(tf, v, lb1 ^ lb2);
5656  }
5657  else if(0<=lb1 && ub1 <= 1 && 0<=lb2 && ub2 <= 1) {
5658  tf = transformer_identity();
5659  /* The two values can be interpreted as booleans */
5660  /* Code about cut-and-pasted from
5661  logical_binary_operation_to_transformer() */
5662  Pvecteur eq1 = vect_new((Variable) v, VALUE_ONE);
5663  vect_add_elem(&eq1, (Variable) tmp_v1, VALUE_MONE);
5664  vect_add_elem(&eq1, (Variable) tmp_v2, VALUE_MONE);
5665 
5666  Pvecteur eq2 = vect_new((Variable) v, VALUE_ONE);
5667  vect_add_elem(&eq2, (Variable) tmp_v1, VALUE_ONE);
5668  vect_add_elem(&eq2, (Variable) tmp_v2, VALUE_ONE);
5670 
5671  Pvecteur eq3 = vect_new((Variable) v, VALUE_MONE);
5672  vect_add_elem(&eq3, (Variable) tmp_v1, VALUE_ONE);
5673  vect_add_elem(&eq3, (Variable) tmp_v2, VALUE_MONE);
5674 
5675  Pvecteur eq4 = vect_new((Variable) v, VALUE_MONE);
5676  vect_add_elem(&eq4, (Variable) tmp_v1, VALUE_MONE);
5677  vect_add_elem(&eq4, (Variable) tmp_v2, VALUE_ONE);
5678 
5679  tf = transformer_inequality_add(tf, eq1);
5680  tf = transformer_inequality_add(tf, eq2);
5681  tf = transformer_inequality_add(tf, eq3);
5682  tf = transformer_inequality_add(tf, eq4);
5683  }
5684  }
5685  if(transformer_undefined_p(tf)) {
5686  /* The two arguments may be equal because they are the same
5687  expression and the xor is used to generate a zero or because
5688  they have the same value. */
5689  if(expression_equal_p(le1, le2)) {
5690  tf = transformer_identity();
5692  }
5693  else {
5694  transformer tfr1 = transformer_range(tf1);
5695  transformer tfr2 = transformer_range(tf2);
5696  transformer tfi = transformer_intersection(tfr1, tfr2);
5698  Pvecteur eq = vect_new((Variable) tmp_d, VALUE_ONE);
5699  vect_add_elem(&eq, (Variable) tmp_v1, VALUE_MONE);
5700  vect_add_elem(&eq, (Variable) tmp_v2, VALUE_ONE);
5701  tfi = transformer_equality_add(tfi, eq);
5702  intptr_t lbd, ubd;
5703 
5704  if(precondition_minmax_of_value(tmp_d, tfi, &lbd, &ubd)) {
5705  if(lbd==0 && ubd==0) {
5706  /* Since the difference is zero the two values are equal */
5707  tf = transformer_identity();
5709  }
5710  }
5711  }
5712  }
5713  //}
5714  //free_basic(be1), free_basic(be2);
5715  free_transformer(tfr1), free_transformer(tfr2);
5716  return tf;
5717 }
5718 ␌
5719 /* Compute the transformer associated to a list of expressions such as
5720  * "i=0, j = 1;". The value returned is ignored.
5721  */
5723  transformer pre)
5724 {
5728 
5729  FOREACH(EXPRESSION, exp, expl) {
5730  /* el is an over-appoximation; should be replaced by a
5731  safe_expression_to_transformer() taking care of computing the
5732  precise effects of exp instead of using the effects of expl. */
5733  transformer cpre_r = transformer_range(cpre);
5736 
5737  tf = transformer_combine(tf, ctf);
5738  tf = transformer_normalize(tf, 2);
5739  npre = transformer_apply(ctf, cpre);
5740  npre = transformer_normalize(npre, 2);
5741  free_transformer(cpre);
5742  free_transformer(cpre_r);
5743  cpre = npre;
5744  }
5745  free_transformer(cpre);
5746  return tf;
5747 }
5748 
5749 /* Compute the transformer associated to a list of expressions such as
5750  * "i=0, j = 1;". The value returned is linked to v.
5751  *
5752  * To be merged with the previous function.
5753  */
5755  list expl,
5756  transformer pre)
5757 {
5761  expression l_exp = EXPRESSION(CAR(gen_last(expl)));
5762 
5763  FOREACH(EXPRESSION, exp, expl) {
5764  /* el is an over-appoximation; should be replaced by a
5765  safe_expression_to_transformer() taking care of computing the
5766  precise effects of exp instead of using the effects of expl. */
5767  transformer ctf = (exp==l_exp)?
5768  safe_any_expression_to_transformer(v, exp, cpre, false) :
5772 
5773  tf = transformer_combine(tf, ctf);
5774  tf = transformer_normalize(tf, 2);
5775  npre = transformer_apply(ctf, cpre);
5776  npre_r = transformer_range(npre);
5777  npre_r = transformer_normalize(npre_r, 2);
5778  free_transformer(cpre);
5779  free_transformer(npre);
5780  free_transformer(ctf);
5781  cpre = npre_r;
5782  }
5783  free_transformer(cpre);
5784  return tf;
5785 }
5786 
5787 /* compute integer bounds @p pmax, @p pmin of value @p val under
5788  * preconditions @p tr require value mappings set !
5789  */
5791  transformer tr,
5792  intptr_t* pmin, intptr_t* pmax)
5793 {
5794  bool success;
5795  /* retrieve the associated psysteme*/
5797  /* compute min / max bounds */
5798  Value vmin,vmax;
5799  if((success=sc_minmax_of_variable(ps,val,&vmin,&vmax)))
5800  {
5801  /* special case to handle VMIN and VMAX in 32 bits*/
5802  if(vmax != (Value)(intptr_t)(vmax) && vmax == VALUE_MAX) vmax= INT_MAX;
5803  if(vmin != (Value)(intptr_t)(vmin) && vmin == VALUE_MIN) vmin= INT_MIN;
5804  pips_assert("no data loss", vmin == (Value)(intptr_t)(vmin));
5805  pips_assert("no data loss", vmax == (Value)(intptr_t)(vmax));
5806  *pmin=(intptr_t)vmin;
5807  *pmax=(intptr_t)vmax;
5808  }
5809  // FI: ps is destroyed by sc_minmax_of_variable(). Should it
5810  // nevertheless be freed?
5811  return success;
5812 }
5813 
5814 
5815 /* compute integer bounds @p pmax, @p pmin of expression @p exp under preconditions @p tr
5816  * require value mappings set !
5817  */
5819  transformer tr, // precondition
5820  intptr_t* pmin,
5821  intptr_t* pmax)
5822 {
5823  bool success;
5824  /* create a temporary value */
5825  basic bas = basic_of_expression(exp);
5827  free_basic(bas);
5828 
5829  /* compute its preconditions */
5830  transformer var_tr = safe_any_expression_to_transformer(var,exp,tr,false);
5831  transformer pre = transformer_apply(var_tr, tr);
5832 
5833  //success = precondition_minmax_of_value(var, var_tr, pmin, pmax);
5834  success = precondition_minmax_of_value(var, pre, pmin, pmax);
5835 
5836  /* tidy & return */
5837  predicate_system(transformer_relation(var_tr))=SC_UNDEFINED;
5838  free_transformer(var_tr);
5839  free_entity(var);
5840  return success;
5841 }
5842 
5843 /* tries hard to simplify expression @p e if it is a min or a max
5844  * operator, by evaluating it under preconditions @p tr.
5845  * Two approaches are tested:
5846  * check bounds of lhs-rhs,
5847  * or compare bounds of lhs and rhs
5848  */
5850 {
5851  if(expression_minmax_p(e)) {
5852  call c =expression_call(e);
5853  bool is_max = ENTITY_MAX_P(call_function(c));
5854 
5855  expression lhs = binary_call_lhs(c);
5856  expression rhs = binary_call_rhs(c);
5857  expression diff = make_op_exp(
5859  copy_expression(lhs),
5860  copy_expression(rhs)
5861  );
5862  intptr_t lhs_lbound,lhs_ubound,rhs_lbound,rhs_ubound,diff_lbound,diff_ubound;
5863  if(precondition_minmax_of_expression(diff,tr,&diff_lbound,&diff_ubound) &&
5864  (diff_lbound>=0 || diff_ubound<=0)) {
5865  if(is_max) {
5866  if(diff_lbound>=0) local_assign_expression(e,lhs);
5867  else local_assign_expression(e,rhs);
5868  }
5869  else {
5870  if(diff_lbound>=0) local_assign_expression(e,rhs);
5871  else local_assign_expression(e,lhs);
5872  }
5873  }
5874  else if(precondition_minmax_of_expression(lhs,tr,&lhs_lbound,&lhs_ubound) &&
5875  precondition_minmax_of_expression(rhs,tr,&rhs_lbound,&rhs_ubound))
5876  {
5877  if(is_max)
5878  {
5879  if(lhs_lbound >=rhs_ubound) local_assign_expression(e,lhs);
5880  else if(rhs_lbound >= lhs_ubound) local_assign_expression(e,rhs);
5881  }
5882  else
5883  {
5884  if(lhs_lbound >=rhs_ubound) local_assign_expression(e,rhs);
5885  else if(rhs_lbound >= lhs_ubound) local_assign_expression(e,lhs);
5886  }
5887  }
5888  }
5889 }
5890 ␌
5892 {
5893  bool result = false;
5894 
5895  result = eval_condition_wrt_precondition_p(c, pre, false);
5896 
5897  return result;
5898 }
5899 
5901 {
5902  bool result = false;
5903 
5904  result = eval_condition_wrt_precondition_p(c, pre, true);
5905 
5906  return result;
5907 }
5908 
5910 {
5911  bool result = false;
5912  transformer f = transformer_dup(pre);
5913 
5914  if(veracity) {
5915  f = precondition_add_condition_information(f, c, pre, false);
5916  }
5917  else {
5918  f = precondition_add_condition_information(f, c, pre, true);
5919  }
5920 
5921  result = transformer_empty_p(f);
5922 
5923  return result;
5924 }
5925 ␌
5926 /* It is supposed to be obsolete but is still called. Maybe, it's only
5927  partly obsolete... If upwards is false, it is worth performing more
5928  convex hulls because the precondition on entry may restrain the space. */
5930  transformer pre,
5931  entity relop,
5932  expression e1,
5933  expression e2,
5934  bool veracity,
5935  bool upwards) /* upwards = transformer, !upwards = precondition */
5936 {
5937 # define DEBUG_TRANSFORMER_ADD_RELATION_INFORMATION 7
5938  /* default: no change */
5939  transformer newpre = pre;
5940  /* both expressions e1 and e2 must be affine */
5943 
5946  "begin upwards=%s veracity=%s relop=%s e1=",
5947  bool_to_string(upwards), bool_to_string(veracity),
5948  entity_local_name(relop));
5949  print_expression(e1);
5950  (void) fprintf(stderr,"e2=");
5951  print_expression(e2);
5952  (void) fprintf(stderr,"pre=");
5953  print_transformer(pre);
5954  }
5955 
5961 
5962  /* Make sure that new values only are used in v1 and v2 */
5965 
5966  if((ENTITY_EQUAL_P(relop) && veracity) ||
5967  (ENTITY_NON_EQUAL_P(relop) && !veracity)) {
5968  /* v1 - v2 == 0 */
5969  Pvecteur v = vect_substract(v1, v2);
5970  if(upwards) {
5971  upwards_vect_rename(v, pre);
5972  }
5973  newpre = transformer_equality_add(pre, v);
5974  }
5975  else if((ENTITY_EQUAL_P(relop) && !veracity) ||
5976  (ENTITY_NON_EQUAL_P(relop) && veracity)) {
5977  /* v2 - v1 + 1 <= 0 ou v1 - v2 + 1 <= 0 */
5978  /* FI: I do not know if this is valid when your are moving upwards
5979  * variables in v2 and v1 may have to be renamed as #init values (i.e. old values)
5980  */
5981  transformer prea = transformer_dup(pre);
5982  transformer preb = pre;
5983  Pvecteur va = vect_substract(v2, v1);
5984  Pvecteur vb = vect_substract(v1, v2);
5985  vect_add_elem(&va, TCST, VALUE_ONE);
5986  vect_add_elem(&vb, TCST, VALUE_ONE);
5987  /* FI: I think that this should be programmed (see comment above)
5988  * but I'm waiting for a bug to occur... (6 July 1993)
5989  *
5990  * FI: Well, the bug was eventually seen:-) (8 November 1995)
5991  */
5992  if(upwards) {
5993  upwards_vect_rename(va, pre);
5994  upwards_vect_rename(vb, pre);
5995  }
5996  prea = transformer_inequality_add(prea, va);
5997  preb = transformer_inequality_add(preb, vb);
5998  newpre = transformer_convex_hull(prea, preb);
5999  /* free_transformer(prea); */
6000  /* free_transformer(preb); */
6001  }
6002  else if ((ENTITY_GREATER_THAN_P(relop) && veracity) ||
6003  (ENTITY_LESS_OR_EQUAL_P(relop) && !veracity)) {
6004  /* v2 - v1 + 1 <= 0 */
6005  Pvecteur v = vect_substract(v2, v1);
6007  if(upwards) {
6008  upwards_vect_rename(v, pre);
6009  }
6010  newpre = transformer_inequality_add(pre, v);
6011  }
6012  else if ((ENTITY_GREATER_THAN_P(relop) && !veracity) ||
6013  (ENTITY_LESS_OR_EQUAL_P(relop) && veracity)) {
6014  /* v1 - v2 <= 0 */
6015  Pvecteur v = vect_substract(v1, v2);
6016  if(upwards) {
6017  upwards_vect_rename(v, pre);
6018  }
6019  newpre = transformer_inequality_add(pre, v);
6020  }
6021  else if ((ENTITY_GREATER_OR_EQUAL_P(relop) && veracity) ||
6022  (ENTITY_LESS_THAN_P(relop) && !veracity)) {
6023  /* v2 - v1 <= 0 */
6024  Pvecteur v = vect_substract(v2, v1);
6025  if(upwards) {
6026  upwards_vect_rename(v, pre);
6027  }
6028  newpre = transformer_inequality_add(pre, v);
6029  }
6030  else if ((ENTITY_GREATER_OR_EQUAL_P(relop) && !veracity) ||
6031  (ENTITY_LESS_THAN_P(relop) && veracity)) {
6032  /* v1 - v2 + 1 <= 0 */
6033  Pvecteur v = vect_substract(v1, v2);
6035  if(upwards) {
6036  upwards_vect_rename(v, pre);
6037  }
6038  newpre = transformer_inequality_add(pre, v);
6039  }
6040  else {
6041  /* do nothing... although Malik may have tried harder! */
6042  newpre = pre;
6043  }
6044  vect_rm(v1);
6045  vect_rm(v2);
6046  }
6047  else
6048  /* do nothing, although MODULO and INTEGER DIVIDE could be handled */
6049  newpre = pre;
6050 
6053  "end newpre=\n");
6054  print_transformer(newpre);
6055  pips_assert("Transformer is internally consistent",
6057  }
6058 
6059  return newpre;
6060 }
6061 ␌
6062 /* Simplification of bool expressions with precondition
6063  *
6064  * Expression e is modified, if necessary, by side effect.
6065  *
6066  * The value returned is 1 if the expression e is always true (never
6067  * false) under condition p, 0 if is the expression is always false
6068  * (never true), and -1 otherwise.
6069  *
6070  * This function is not used within the semantics library. It is
6071  * exported for partial_eval and suppress_dead_code or similar passes.
6072  *
6073  * Because of C flexibility, all kinds of "boolean" expressions may
6074  * arise. Think of the conditional and comma operators, think of all
6075  * kinds of side effects, think of integer expressions,...
6076  *
6077  * FI: In the short term, I only need to deal with bool operators
6078  * and, or and not.
6079  */
6081  transformer p)
6082 {
6083  int validity = -1; // unknown
6084  bool done = false;
6086  // We could try the global simplification as in the other case...
6087  syntax s = expression_syntax(e);
6088  call c = syntax_call(s);
6089  entity op = call_function(c);
6090  if(ENTITY_NOT_P(op)) {
6093  if(validity>=0)
6094  validity = 1 - validity;
6095  done = true;
6096  }
6097  else if(ENTITY_OR_P(op)) {
6100  if(v1==1)
6101  validity = 1;
6102  else {
6105  if(v2==1)
6106  validity = 1;
6107  else if(v2==0) { // a2 has no impact
6108  if(v1==0)
6109  validity = 0;
6110  else {
6111  validity = -1;
6113  }
6114  }
6115  else // v2==-1
6116  if(v1==0) { // a1 has no impact
6117  validity = -1;
6119  }
6120  else
6121  validity = -1;
6122  }
6123  done =true;
6124  }
6125  else if(ENTITY_AND_P(op)) {
6128  if(v1==0)
6129  validity = 0;
6130  else { // v1 == -1 or 1, no conclusion yet
6133  if(v2==0)
6134  validity = 0;
6135  else if(v2==1) {
6136  if(v1==1)
6137  validity = 1;
6138  else { // get rid of a2
6139  validity = -1;
6141  }
6142  }
6143  else { // v2==-1
6144  if(v1==1) {// a1 is useless
6145  validity = -1;
6147  }
6148  else {
6149  validity = -1;
6150  }
6151  }
6152  }
6153  done =true;
6154  }
6155  }
6156  if (!done) {
6157  transformer tt = condition_to_transformer(e,p, true);
6158  transformer ft = condition_to_transformer(e,p, false);
6159 
6160  if(transformer_empty_p(tt)) {
6161  // Then the condition is always false
6162  validity = 0;
6163  }
6164  if(transformer_empty_p(ft)) {
6165  // Then the condition is always true
6166  validity = 1;
6167  }
6168  // Both can be true simultaneously when the precondition p is
6169  // empty... but it does not matter
6170  }
6171 
6172  if(validity==0||validity==1) {
6173  // e must be replaced by a call to true or false
6176  }
6177 
6178  return validity;
6179 }
6180 
6181 /* See if references rlhs is usable and process null, undefined and
6182  * anywhere locations defined by rlhs.
6183  *
6184  * Expression lhs is passed to clarify the error and warning messages.
6185  *
6186  * n is the number of alternative references. It is used to check the
6187  * severity of unusable references. If n=1, a NULL rlhs implies a
6188  * bug. If n>1, the points-to analysis could not determine precisely
6189  * the target location.
6190  *
6191  * This function is designed to check constant references in a loop
6192  * over a list of references returned by the points-to analysis.
6193 */
6195 {
6196  bool usable_p = false;
6197  entity source_lhs = reference_variable(rlhs);
6198  string lhss = expression_undefined_p(lhs)?
6200 
6201  ifdebug(7) {
6202  pips_debug(7, "source reference : %s\n", reference_to_string(rlhs));
6203  }
6204 
6205  if (entity_null_locations_p(source_lhs)) {
6206  if (n == 1)
6207  // An empty transformer should be returned...
6208  pips_user_error("The pointer expression \"%s\" always points to NULL\n",
6209  lhss);
6210  else
6211  semantics_user_warning("The pointer \"%s\" can point to NULL\n",
6212  lhss);
6213  }
6214  else if (entity_typed_nowhere_locations_p(source_lhs)) {
6215  if (n == 1)
6216  pips_user_error("The pointer expression \"%s\" always points to undefined/indeterminate (%s)\n", lhss, reference_to_string(rlhs));
6217  else {
6218  semantics_user_warning("The pointer expression \"%s\" can point to undefined/indeterminate (%s)\n", lhss, reference_to_string(rlhs));
6219  }
6220  }
6221  else if(entity_heap_location_p(source_lhs)) {
6222  // entity_all_heap_locations_p()
6223  // entity_all_module_heap_locations_p()
6224  // entity_all_module_heap_locations_typed : the predicate does not seem to exist
6225  /* A heap location may represent several locations. p==heap ^
6226  q==heap does not imply p==q */
6227  usable_p = false;
6228  }
6229  else if(entity_anywhere_locations_p(source_lhs)
6230  || entity_typed_anywhere_locations_p(source_lhs)) {
6231  /* An anywhere location may represent several locations. p==heap ^
6232  q==heap does not imply p==q */
6233  usable_p = false;
6234  }
6235  else {
6236  // usable_p = atomic_points_to_reference_p(rlhs);
6238  usable_p = analyzed_type_p(t)
6240  }
6241 
6242  ifdebug(7) {
6243  pips_debug(7, "source reference \"%s\" is %s\n", reference_to_string(rlhs),
6244  usable_p ? "usable" : "not usable");
6245  }
6246 
6247  return usable_p;
6248 }
6249 
6250 /* This function deals with e1.e2 and e1->e2, not with simple
6251  * references such as x or a[i].
6252  *
6253  * This piece of code has mainly been retrieved from
6254  * any_assign_to_transformer().
6255  *
6256  * FI: I am not sure how to factorize it out because entity e
6257  * corresponds to some memory location and is modified in an
6258  * assignement environment. Here, e is likely to be a temporary
6259  * value. It is not updated. It should not appear among the
6260  * transformer arguments
6261  */
6263 {
6264  syntax slhs = expression_syntax(lhs);
6266 
6267  if(syntax_call_p(slhs)) {
6270  int n = (int) gen_length(l);
6271  // FI: I wonder what happens with side effects in the rhs and
6272  // with pointer dereferencing in the rhs
6273  FOREACH(CELL, cp, l) {
6275 
6276  // example of case which is normally filter *p when p formal
6277  // parameter, or dynamic allocation of p
6278  if(semantics_usable_points_to_reference_p(rlhs, lhs, n)) {
6279  if (analyzed_reference_p(rlhs)) {
6281 
6282  if(!entity_undefined_p(ecp)) { // the location is analyzed
6283  // The preconditions may make the convex hull useful when
6284  // different locations have known values or are
6285  // constrained
6286  transformer rt = copy_transformer(pre);
6287  rt = transformer_add_equality(rt, e, ecp);
6288 
6289  // NL : a better way to do this may exit but I don't know it
6290  if (transformer_undefined_p(tf))
6291  tf = rt;
6292  else {
6293  tf = transformer_convex_hull(tf, rt);
6294  free_transformer(rt);
6295  }
6296  }
6297  }
6298  }
6299  }
6300  }
6301  }
6302  else {
6303  // It might be more useful to process the reference for side effects
6304  pips_internal_error("Improper argument.\n");
6305  }
6306  return tf;
6307 }
float a2sf[2] __attribute__((aligned(16)))
USER generates a user error (i.e., non fatal) by printing the given MSG according to the FMT.
Definition: 3dnow.h:3
void free_transformer(transformer p)
Definition: ri.c:2616
transformer make_transformer(list a1, predicate a2)
Definition: ri.c:2649
void free_entity(entity p)
Definition: ri.c:2524
predicate make_predicate(Psysteme a1)
Definition: ri.c:1820
basic copy_basic(basic p)
BASIC.
Definition: ri.c:104
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
void free_expression(expression p)
Definition: ri.c:853
void free_type(type p)
Definition: ri.c:2658
void free_basic(basic p)
Definition: ri.c:107
transformer copy_transformer(transformer p)
TRANSFORMER.
Definition: ri.c:2613
bool entity_heap_location_p(entity b)
package abstract location.
bool active_phase_p(const char *phase)
Definition: activate.c:80
bool entity_null_locations_p(entity e)
test if an entity is the NULL POINTER
bool entity_typed_anywhere_locations_p(entity e)
Test if an entity is the bottom of the lattice.
bool entity_anywhere_locations_p(entity e)
test if an entity is the bottom of the lattice
bool entity_typed_nowhere_locations_p(entity e)
test if an entity is the bottom of the lattice
bool entity_is_argument_p(entity e, cons *args)
Definition: arguments.c:150
#define value_lshift(v1, v2)
#define VALUE_ZERO
#define int_to_value(i)
end LINEAR_VALUE_IS_INT
void const char const char const int
#define VALUE_MIN
#define VALUE_MONE
#define MIN(x, y)
minimum and maximum if they are defined somewhere else, they are very likely to be defined the same w...
int Value
#define VALUE_MAX
#define VALUE_ONE
Value exponentiate(Value, int)
exp.c
Definition: exp.c:45
Pbase base_add_variable(Pbase b, Variable var)
Pbase base_add_variable(Pbase b, Variable v): add variable v as a new dimension to basis b at the end...
Definition: base.c:88
Pvecteur vect_variable_rename(Pvecteur v, Variable v_old, Variable v_new)
Pvecteur vect_variable_rename(Pvecteur v, Variable v_old, Variable v_new): rename the potential coord...
Definition: base.c:366
bool transformer_argument_consistency_p(transformer t)
Definition: basic.c:551
transformer transformer_add_inequality_with_linear_term(transformer tf, entity v, entity x, int a, bool less_than_p)
Add the inequality v <= a x or v >= a x.
Definition: basic.c:530
transformer transformer_add_modified_variable(transformer tf, entity var)
FI: this function does not end up with a consistent transformer because the old value is not added to...
Definition: basic.c:889
transformer transformer_dup(transformer t_in)
transformer package - basic routines
Definition: basic.c:49
bool transformer_identity_p(transformer t)
Check that t is an identity function.
Definition: basic.c:154
transformer transformer_add_sign_information(transformer tf, entity v, int v_sign)
CHANGE THIS NAME: no loop index please, it's not directly linked to loops!!!
Definition: basic.c:200
void transformer_free(transformer t)
Definition: basic.c:68
transformer transformer_add_inequality_with_integer_constraint(transformer tf, entity v, long long int cst, bool less_than_p)
Add the inequality v <= cst or v >= cst.
Definition: basic.c:477
transformer transformer_add_3d_affine_constraint(transformer tf, int a1, entity v1, int a2, entity v2, int a3, entity v3, int cst, bool equation_p)
Add the constraint a1 v1 + a2 v2 + a3 v3 + cst <= or == 0.
Definition: basic.c:536
transformer transformer_inequality_add(transformer tf, Pvecteur i)
Definition: basic.c:375
transformer transformer_add_equality_with_integer_constant(transformer tf, entity v, long long int cst)
Add an equality between a value and an integer constant: v==cst.
Definition: basic.c:450
transformer transformer_inequalities_add(transformer tf, Pcontrainte ineqs)
Warning:
Definition: basic.c:409
transformer transformer_equality_add(transformer tf, Pvecteur i)
Definition: basic.c:383
transformer empty_transformer(transformer t)
Do not allocate an empty transformer, but transform an allocated transformer into an empty_transforme...
Definition: basic.c:144
transformer transformer_identity()
Allocate an identity transformer.
Definition: basic.c:110
transformer transformer_add_inequality_with_affine_term(transformer tf, entity v, entity x, int a, int cst, bool less_than_p)
Add the inequality v <= a x + cst or v >= a x + cst.
Definition: basic.c:496
transformer transformer_empty()
Allocate an empty transformer.
Definition: basic.c:120
transformer transformer_add_equality(transformer tf, entity v1, entity v2)
Add an equality between two values (two variables?)
Definition: basic.c:436
transformer transformer_add_variable_update(transformer t, entity v)
Add an update of variable v into t.
Definition: basic.c:289
bool transformer_internal_consistency_p(transformer t)
Same as above but equivalenced variables should not appear in the argument list or in the predicate b...
Definition: basic.c:790
transformer transformer_add_equality_with_affine_term(transformer tf, entity v, entity x, int a, int cst)
Add the equality v = a x + cst.
Definition: basic.c:517
transformer transformer_add_inequality(transformer tf, entity v1, entity v2, bool strict_p)
Add the equality v1 <= v2 or v1 < v2.
Definition: basic.c:464
bdt base
Current expression.
Definition: bdt_read_paf.c:100
entity make_constant_entity(string name, tag bt, size_t size)
For historical reason, call the Fortran version.
Definition: constant.c:301
double float_constant_to_double(entity c)
Definition: constant.c:639
bool integer_constant_p(entity ent, int *int_p)
Returns the double value associated to a PIPS constant.
Definition: constant.c:542
bool float_constant_p(entity ent)
ent can be either a numerical or a symbolic float constant
Definition: constant.c:487
bool logical_constant_p(entity ent)
Definition: constant.c:463
#define CONTRAINTE_UNDEFINED_P(c)
#define CONTRAINTE_NULLE_P(c)
contrainte nulle (non contrainte 0 == 0 ou 0 <= 0)
#define CONTRAINTE_UNDEFINED
Pcontrainte contraintes_free(Pcontrainte pc)
Pcontrainte contraintes_free(Pcontrainte pc): desallocation de toutes les contraintes de la liste pc.
Definition: alloc.c:226
Pcontrainte contrainte_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
bool test_warning_counters(void)
list expression_to_proper_constant_path_effects(expression)
bool location_entity_p(entity)
Definition: locations.c:349
type points_to_reference_to_concrete_type(reference)
Definition: type.c:685
reference cell_any_reference(cell)
API for reference.
Definition: effects.c:77
entity null_pointer_value_entity(void)
bool pt_to_list_undefined_p(void)
points_to.c
bool effect_list_can_be_safely_full_freed_p(list)
Check if some references might be freed with the effects.
Definition: effects.c:1159
entity constant_memory_access_path_to_location_entity(reference)
A constant memory access path may not be considered.
Definition: locations.c:329
bool null_pointer_value_entity_p(entity)
#define cell_reference(x)
Definition: effects.h:469
#define cell_preference(x)
Definition: effects.h:472
#define CELL(x)
CELL.
Definition: effects.h:424
#define cell_preference_p(x)
Definition: effects.h:470
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
void * malloc(YYSIZE_T)
void free(void *)
bool success
Definition: gpips-local.h:59
bool references_may_conflict_p(reference r1, reference r2)
Check if two references may conflict.
Definition: conflicts.c:426
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define 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
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
list gen_last(list l)
Return the last element of a list.
Definition: list.c:578
#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 list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
void vect_dump(Pvecteur v)
void vect_dump(Pvecteur v): print sparse vector v on stderr.
Definition: io.c:304
#define _UNUSED_
Definition: misc-local.h:232
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#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 pips_user_error
Definition: misc-local.h:147
string bool_to_string(bool)
Definition: string.c:243
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
@ is_max
Definition: optimize.c:710
@ is_min
Definition: optimize.c:710
string reference_to_string(reference r)
Definition: expression.c:87
void print_expression(expression e)
no file descriptor is passed to make is easier to use in a debugging stage.
Definition: expression.c:58
string expression_to_string(expression e)
Definition: expression.c:77
#define print_transformer(t)
Definition: print.c:357
#define dump_transformer(t)
Definition: print.c:355
string basic_to_string(basic)
Definition: type.c:87
#define SEMANTICS_INTERPROCEDURAL
#define ENTITY_OR_P(e)
#define ENTITY_PLUS_UPDATE_P(e)
#define ENTITY_DIVIDE_P(e)
#define ENTITY_RELATIONAL_OPERATOR_P(e)
#define ENTITY_POWER_P(e)
#define ENTITY_DMAX1_P(e)
#define ENTITY_DABS_P(e)
#define GREATER_THAN_OPERATOR_NAME
#define ENTITY_AND_P(e)
#define ENTITY_NON_EQUAL_P(e)
#define binary_call_rhs(c)
#define ENTITY_EQUAL_P(e)
#define ENTITY_MAX0_P(e)
#define ENTITY_LEFT_SHIFT_P(e)
#define ENTITY_ASSIGN_P(e)
#define MINUS_OPERATOR_NAME
#define ENTITY_FABSL_P(e)
#define ENTITY_MINUS_P(e)
#define LESS_THAN_OPERATOR_NAME
#define ENTITY_COMMA_P(e)
#define ENTITY_UNARY_MINUS_P(e)
#define ENTITY_DEREFERENCING_P(e)
#define ENTITY_CABSL_P(e)
#define ENTITY_FABS_P(e)
#define ENTITY_TRUE_P(e)
#define ENTITY_AMIN1_P(e)
#define ENTITY_PLUS_P(e)
#define ENTITY_LESS_THAN_P(e)
#define ENTITY_CABSF_P(e)
#define ENTITY_ONE_P(e)
#define ENTITY_MULTIPLY_P(e)
#define ENTITY_C_CABS_P(e)
#define NORMALIZE_EXPRESSION(e)
#define ENTITY_POINT_TO_P(e)
#define ENTITY_PRE_DECREMENT_P(e)
#define ENTITY_CONTINUE_P(e)
#define ENTITY_POST_DECREMENT_P(e)
#define ENTITY_C_MAX_P(e)
#define ENTITY_IMAXABS_P(e)
#define ENTITY_POST_INCREMENT_P(e)
#define ENTITY_CONDITIONAL_P(e)
#define ENTITY_CABS_P(e)
#define ENTITY_C_ABS_P(e)
#define ENTITY_PRE_INCREMENT_P(e)
#define ENTITY_NOT_P(e)
#define ENTITY_C_MIN_P(e)
#define ENTITY_PLUS_C_P(e)
#define ENTITY_LLABS_P(e)
#define ENTITY_MAX_P(e)
#define ENTITY_RAND_P(e)
#define ENTITY_GREATER_THAN_P(e)
#define ENTITY_IABS_P(e)
#define ENTITY_FIELD_P(e)
C data structure and pointer management.
#define ENTITY_LOGICAL_OPERATOR_P(e)
Attention : This definition is different with the Fortran Standard where the logical operators are th...
#define ENTITY_MINUS_C_P(e)
#define ENTITY_RIGHT_SHIFT_P(e)
#define binary_call_lhs(c)
#define ENTITY_AMAX1_P(e)
#define ENTITY_BITWISE_OR_P(e)
#define ENTITY_BITWISE_XOR_P(e)
#define ENTITY_MIN0_P(e)
#define ENTITY_ABS_P(e)
#define ENTITY_MIN_P(e)
#define ENTITY_LABS_P(e)
#define ENTITY_ADDRESS_OF_P(e)
#define ENTITY_LESS_OR_EQUAL_P(e)
#define ENTITY_DMIN1_P(e)
#define ENTITY_FALSE_P(e)
#define ENTITY_MINUS_UPDATE_P(e)
#define ENTITY_FABSF_P(e)
#define ENTITY_BITWISE_AND_P(e)
#define entity_constant_p(e)
#define ENTITY_C_MODULO_P(e)
#define ENTITY_GREATER_OR_EQUAL_P(e)
#define ENTITY_ZERO_P(e)
#define ENTITY_MODULO_P(e)
#define PLUS_C_OPERATOR_NAME
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
bool intrinsic_entity_p(entity e)
Definition: entity.c:1272
entity update_operator_to_regular_operator(entity op)
Returns the binary operator associated to a C update operator such as +=.
Definition: entity.c:2154
entity local_name_to_top_level_entity(const char *n)
This function try to find a top-level entity from a local name.
Definition: entity.c:1450
basic entity_basic(entity e)
return the basic associated to entity e if it's a function/variable/constant basic_undefined otherwis...
Definition: entity.c:1380
bool entity_field_p(entity e)
e is the field of a structure
Definition: entity.c:857
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
bool entity_module_p(entity e)
Definition: entity.c:683
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
value EvalSizeofexpression(sizeofexpression soe)
Definition: eval.c:210
subscript expression_subscript(expression e)
Definition: expression.c:1843
bool expression_sizeofexpression_p(expression e)
Definition: expression.c:460
bool expression_opposite_p(expression e1, expression e2)
e1+e2==0, i.e.
Definition: expression.c:1386
bool expression_minmax_p(expression e)
Definition: expression.c:3882
application expression_application(expression e)
Definition: expression.c:485
bool logical_operator_expression_p(expression e)
C xor is missing.
Definition: expression.c:573
bool expression_constant_p(expression exp)
================================================================
Definition: expression.c:2453
bool expression_call_p(expression e)
Definition: expression.c:415
bool call_constant_p(call c)
bool call_constant_p(call c): Returns true if "c" is a call to a constant, that is,...
Definition: expression.c:1965
bool expression_cast_p(expression e)
Definition: expression.c:450
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
bool expression_subscript_p(expression e)
Definition: expression.c:1838
bool expression_null_p(expression exp)
returns true if the expression is equal to zero or NULL (even if there is a cast before such as in (v...
Definition: expression.c:2611
void local_assign_expression(expression caller, expression field)
replace expression caller by expression field , where field is contained by caller
Definition: expression.c:3571
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
expression replace_expression_content(expression e1, expression e2)
Use side effects to move the content of e2, s2 and n2, into e1; s1 and n1 are freed,...
Definition: expression.c:3864
expression make_zero_expression(void)
Make a zero expression.
Definition: expression.c:1212
bool expression_equal_p(expression e1, expression e2)
Syntactic equality e1==e2.
Definition: expression.c:1347
call expression_call(expression e)
Definition: expression.c:445
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
cast expression_cast(expression e)
Definition: expression.c:455
expression make_op_exp(char *op_name, expression exp1, expression exp2)
================================================================
Definition: expression.c:2012
bool integer_constant_expression_p(expression e)
positive integer constant expression: call to a positive constant or to a sum of positive integer con...
Definition: expression.c:903
bool comma_expression_p(expression e)
Definition: expression.c:830
expression make_false_expression()
Definition: expression.c:1108
bool expression_application_p(expression e)
Duplicate bool expression_subscript_p(expression e) { return(syntax_subscript_p(expression_syntax(e))...
Definition: expression.c:480
sizeofexpression expression_sizeofexpression(expression e)
Definition: expression.c:465
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
bool store_independent_reference_p(reference r)
Does this reference define the same set of memory locations regardless of the current (environment an...
Definition: expression.c:3108
bool unbounded_expression_p(expression e)
Definition: expression.c:4329
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
expression make_true_expression()
Definition: expression.c:1103
int integer_constant_expression_value(expression e)
Definition: expression.c:1545
bool c_language_module_p(entity m)
Definition: module.c:447
basic basic_of_expression(expression)
basic basic_of_expression(expression exp): Makes a basic of the same basic as the expression "exp".
Definition: type.c:1383
type ultimate_type(type)
Definition: type.c:3466
bool array_type_p(type)
Definition: type.c:2942
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 type_equal_p(type, type)
Definition: type.c:547
bool integer_type_p(type)
Definition: type.c:3298
type entity_basic_concrete_type(entity)
retrieves or computes and then returns the basic concrete type of an entity
Definition: type.c:3677
type compute_basic_concrete_type(type)
computes a new type which is the basic concrete type of the input type (this new type is not stored i...
Definition: type.c:3556
int string_type_size(basic)
Definition: type.c:1047
bool type_struct_variable_p(type)
Definition: type.c:3867
bool volatile_variable_p(variable)
Definition: variable.c:1649
#define type_enum_p(x)
Definition: ri.h:2968
@ is_basic_derived
Definition: ri.h:579
@ is_basic_string
Definition: ri.h:576
@ is_basic_float
Definition: ri.h:572
@ is_basic_bit
Definition: ri.h:577
@ is_basic_pointer
Definition: ri.h:578
@ is_basic_overloaded
Definition: ri.h:574
@ is_basic_int
Definition: ri.h:571
@ is_basic_logical
Definition: ri.h:573
@ is_basic_typedef
Definition: ri.h:580
@ is_basic_complex
Definition: ri.h:575
#define value_code_p(x)
Definition: ri.h:3065
#define basic_pointer(x)
Definition: ri.h:637
#define syntax_reference_p(x)
Definition: ri.h:2728
#define transformer_undefined
Definition: ri.h:2847
#define functional_result(x)
Definition: ri.h:1444
#define transformer_undefined_p(x)
Definition: ri.h:2848
#define value_constant(x)
Definition: ri.h:3073
#define basic_int_p(x)
Definition: ri.h:614
#define syntax_reference(x)
Definition: ri.h:2730
#define syntax_tag(x)
Definition: ri.h:2727
#define value_reference(x)
Definition: ri.h:3085
#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 basic_derived(x)
Definition: ri.h:640
#define basic_typedef_p(x)
Definition: ri.h:641
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#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 syntax_cast(x)
Definition: ri.h:2739
#define type_functional(x)
Definition: ri.h:2952
#define syntax_application(x)
Definition: ri.h:2748
#define basic_tag(x)
Definition: ri.h:613
#define type_variable(x)
Definition: ri.h:2949
#define basic_pointer_p(x)
Definition: ri.h:635
#define basic_derived_p(x)
Definition: ri.h:638
#define syntax_sizeofexpression_p(x)
Definition: ri.h:2740
@ 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 value_constant_p(x)
Definition: ri.h:3071
#define basic_overloaded_p(x)
Definition: ri.h:623
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define cast_expression(x)
Definition: ri.h:747
#define basic_typedef(x)
Definition: ri.h:643
#define application_arguments(x)
Definition: ri.h:510
#define subscript_indices(x)
Definition: ri.h:2563
#define type_undefined_p(x)
Definition: ri.h:2884
#define entity_undefined_p(x)
Definition: ri.h:2762
#define entity_undefined
Definition: ri.h:2761
#define constant_int_p(x)
Definition: ri.h:848
#define expression_undefined
Definition: ri.h:1223
#define type_void_p(x)
Definition: ri.h:2959
#define entity_name(x)
Definition: ri.h:2790
#define transformer_relation(x)
Definition: ri.h:2873
#define transformer_arguments(x)
Definition: ri.h:2871
#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 syntax_call(x)
Definition: ri.h:2736
#define cast_type(x)
Definition: ri.h:745
#define preference_reference(x)
Definition: ri.h:2102
#define expression_undefined_p(x)
Definition: ri.h:1224
#define subscript_array(x)
Definition: ri.h:2561
#define application_function(x)
Definition: ri.h:508
#define variable_dimensions(x)
Definition: ri.h:3122
#define type_undefined
Definition: ri.h:2883
#define syntax_subscript(x)
Definition: ri.h:2745
#define call_arguments(x)
Definition: ri.h:711
#define syntax_cast_p(x)
Definition: ri.h:2737
#define basic_string_p(x)
Definition: ri.h:629
#define entity_type(x)
Definition: ri.h:2792
#define normalized_linear(x)
Definition: ri.h:1781
#define expression_syntax(x)
Definition: ri.h:1247
#define type_variable_p(x)
Definition: ri.h:2947
#define predicate_system(x)
Definition: ri.h:2069
#define variable_basic(x)
Definition: ri.h:3120
#define basic_logical_p(x)
Definition: ri.h:620
#define basic_float_p(x)
Definition: ri.h:617
#define entity_initial(x)
Definition: ri.h:2796
transformer user_function_call_to_transformer(entity e, expression expr, transformer pre)
a function call is a call to a non void function in C and to a FUNCTION in Fortran
transformer effects_to_transformer(list e)
list of effects
transformer user_call_to_transformer(entity f, list pc, transformer pre, list ef)
transformer assigned_expression_to_transformer(entity v, expression expr, transformer pre)
transformer assigned_expression_to_transformer(entity e, expression expr, list ef): returns a transfo...
transformer call_to_transformer(call c, transformer pre, list ef)
Use to be static, but may be called from expressions in C.
Psysteme sc_make(Pcontrainte leg, Pcontrainte lineg)
Psysteme sc_make(Pcontrainte leg, Pcontrainte lineg): allocation et initialisation d'un systeme d'equ...
Definition: sc.c:78
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
bool sc_minmax_of_variable(Psysteme ps, Variable var, Value *pmin, Value *pmax)
void sc_minmax_of_variable(Psysteme ps, Variable var, Value *pmin, *pmax): examine un systeme pour tr...
Definition: sc_eval.c:143
Value b2
Definition: sc_gram.c:105
Value b1
booleen indiquant quel membre est en cours d'analyse
Definition: sc_gram.c:105
Pcontrainte eq
element du vecteur colonne du systeme donne par l'analyse
Definition: sc_gram.c:108
Pvecteur cp
pointeur sur l'egalite ou l'inegalite courante
Definition: sc_read.c:87
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
Pvecteur vect_multiply(Pvecteur v, Value x)
Pvecteur vect_multiply(Pvecteur v, Value x): multiplication du vecteur v par le scalaire x,...
Definition: scalaires.c:123
#define semantics_user_warning
transformer any_assign_operation_to_transformer(entity tmp, list args, transformer pre, bool is_internal __attribute__((unused)))
Similar to any_assign_to_transformer(), which is a simpler case.
Definition: expression.c:499
transformer safe_integer_expression_to_transformer(entity v, expression expr, transformer pre, bool is_internal)
Always return a defined transformer, using effects in case a more precise analysis fails.
Definition: expression.c:3552
static bool have_sizeof_value_in_multiply_pointer_expression_p(expression expr)
Maybe move in ri-util/expression.c or in effect-util/pointer_values.c.
Definition: expression.c:4268
static transformer pointer_unary_operation_to_transformer(entity e, entity op, expression e1, transformer pre, bool is_internal)
Definition: expression.c:4316
transformer transformer_add_integer_relation_information(transformer pre, entity relop, expression e1, expression e2, bool veracity, bool upwards)
It is supposed to be obsolete but is still called.
Definition: expression.c:5929
static transformer pointer_call_expression_to_transformer(entity e, expression expr, transformer pre, bool is_internal)
Definition: expression.c:4495
bool semantics_usable_points_to_reference_p(reference rlhs, expression lhs, int n)
See if references rlhs is usable and process null, undefined and anywhere locations defined by rlhs.
Definition: expression.c:6194
static transformer iabs_to_transformer(entity v, expression expr, transformer pre, bool is_internal)
Definition: expression.c:1693
static int semantics_basic_tag(basic b)
Assimilate enum and logical to int (used when they appear in logical operations)
Definition: expression.c:4670
static transformer modulo_of_a_positive_value_to_transformer(entity e, int lb1, int ub1, int lb2, int ub2)
Definition: expression.c:1424
static transformer update_operation_to_transformer(entity v, entity op, expression e1, expression e2, transformer pre, bool is_internal)
v = (e1 = e1 op e2) ; e1 must be a reference; does not compute information for dereferenced pointers ...
Definition: expression.c:590
static transformer integer_call_expression_to_transformer(entity e, expression expr, transformer pre, bool is_internal)
Definition: expression.c:3361
transformer affine_increment_to_transformer(entity e, Pvecteur a)
Definition: expression.c:1269
transformer safe_any_expression_to_transformer(entity v, expression expr, transformer pre, bool is_internal)
Always return a usable transformer.
Definition: expression.c:5156
static transformer integer_minmax_to_transformer(entity v, list args, transformer pre, bool is_min, bool is_internal)
Definition: expression.c:2655
static transformer logical_reference_to_transformer(entity v, entity r, bool is_internal)
v is assumed to be a temporary value and r a logical program variable
Definition: expression.c:3894
static transformer float_binary_operation_to_transformer(entity e, entity op, expression e1, expression e2, transformer pre, bool is_internal)
Definition: expression.c:4074
transformer points_to_unary_operation_to_transformer(entity e, entity op, expression e1, transformer pre, bool is_internal, bool is_pointer)
This function is redundant with generic_unary_operation_to_transformer() except for its use of parame...
Definition: expression.c:2770
transformer transformer_add_any_relation_information(transformer pre, entity op, expression e1, expression e2, transformer context, bool veracity, bool upwards)
compute transformer or precondition
Definition: expression.c:4686
transformer safe_any_assign_operation_to_transformer(entity tmp, list args, transformer pre, bool is_internal)
Definition: expression.c:575
static transformer float_call_expression_to_transformer(entity v, expression expr, transformer pre, bool is_internal)
Definition: expression.c:4095
static transformer logical_binary_function_to_transformer(entity v, call c, transformer pre, bool is_internal)
Definition: expression.c:3769
transformer expression_effects_to_transformer(expression expr)
Definition: expression.c:3465
static transformer logical_unary_operation_to_transformer(entity v, call c, transformer pre, bool is_internal)
Definition: expression.c:3607
bool false_condition_wrt_precondition_p(expression c, transformer pre)
Definition: expression.c:5891
bool precondition_minmax_of_value(entity val, transformer tr, intptr_t *pmin, intptr_t *pmax)
compute integer bounds pmax, pmin of value val under preconditions tr require value mappings set !
Definition: expression.c:5790
transformer affine_to_transformer(entity e, Pvecteur a, bool assignment)
Definition: expression.c:1212
static transformer modulo_of_a_constant_to_transformer(entity e, int lb1, int lb2, int ub2)
Definition: expression.c:1278
transformer generic_reference_to_transformer(entity v, reference r, transformer pre, bool is_internal)
TYPE INDEPENDENT OPERATIONS.
Definition: expression.c:126
static transformer transformer_add_ored_conditions_updown(transformer pre, expression c1, expression c2, transformer context, bool veracity, bool upwards)
call transformer_add_condition_information_updown() recursively on both sub-expressions if veracity =...
Definition: expression.c:820
static transformer generic_abs_to_transformer(entity, expression, transformer, bool)
forward declaration
Definition: expression.c:1725
transformer any_expression_to_transformer(entity v, expression expr, transformer pre, bool is_internal)
A set of functions to compute the transformer associated to an expression evaluated in a given contex...
Definition: expression.c:4993
transformer any_basic_update_operation_to_transformer(entity tmp, entity v, entity op)
See also any_basic_update_to_transformer(), which should be based on this function.
Definition: expression.c:317
static transformer transformer_add_condition_information_updown(transformer, expression, transformer, bool, bool)
call transformer_add_condition_information_updown() recursively on both sub-expressions if veracity =...
Definition: expression.c:961
static transformer max0_to_transformer(entity e, list args, transformer pre, bool is_internal)
Definition: expression.c:2728
transformer precondition_add_condition_information(transformer pre, expression c, transformer context, bool veracity)
context might be derivable from pre as transformer_range(pre) but this is sometimes very computationa...
Definition: expression.c:1111
static transformer generic_minmax_to_transformer(entity e, list args, transformer pre, bool minmax, bool is_internal)
Definition: expression.c:214
static transformer float_unary_operation_to_transformer(entity e, entity op, expression e1, transformer pre, bool is_internal)
Definition: expression.c:4054
static transformer integer_divide_to_transformer(entity e, expression arg1, expression arg2, transformer pre, bool is_internal)
More could be done along the line of integer_multiply_to_transformer()...
Definition: expression.c:1780
int simplify_boolean_expression_with_precondition(expression e, transformer p)
Simplification of bool expressions with precondition.
Definition: expression.c:6080
transformer any_expressions_to_transformer(entity v, list expl, transformer pre)
Compute the transformer associated to a list of expressions such as "i=0, j = 1;".
Definition: expression.c:5754
transformer bitwise_xor_to_transformer(entity v, list args, transformer pre)
returns the transformer associated to a C bitwise xor, ^, applied to two integer argument,...
Definition: expression.c:5619
transformer pointer_expression_to_transformer(entity v, expression expr, transformer pre, bool is_internal)
Definition: expression.c:4582
transformer transformer_add_domain_condition(transformer tf, expression c, transformer context, bool veracity)
Definition: expression.c:1138
static transformer unary_minus_operation_to_transformer(entity v, expression e1, transformer pre, bool is_internal)
Type independent.
Definition: expression.c:288
transformer expressions_to_transformer(list expl, transformer pre)
Compute the transformer associated to a list of expressions such as "i=0, j = 1;".
Definition: expression.c:5722
transformer expression_to_transformer(expression exp, transformer pre, list el)
Just to capture side effects as the returned value is ignored.
Definition: expression.c:5190
bool precondition_minmax_of_expression(expression exp, transformer tr, intptr_t *pmin, intptr_t *pmax)
compute integer bounds pmax, pmin of expression exp under preconditions tr require value mappings set...
Definition: expression.c:5818
static transformer integer_right_shift_to_transformer(entity e, expression arg1, expression arg2, transformer pre, bool is_internal)
More could be done along the line of integer_left_shift_to_transformer()...
Definition: expression.c:1827
transformer transformer_add_condition_information(transformer pre, expression c, transformer context, bool veracity)
Definition: expression.c:1092
static transformer modulo_to_transformer(entity e, expression arg1, expression arg2, transformer pre, bool is_internal __attribute__((unused)))
Modulo and integer division.
Definition: expression.c:1580
transformer logical_intrinsic_to_transformer(entity v, call c, transformer pre, bool is_internal)
Definition: expression.c:3911
static list expression_to_points_to_sources(_UNUSED_ expression e, _UNUSED_ points_to_graph in)
Definition: expression.c:108
static transformer integer_left_shift_to_transformer(entity v, expression e1, expression e2, transformer prec, bool is_internal)
Assumes that e1 and e2 are integer expressions, i.e.
Definition: expression.c:2303
static bool have_null_value_in_pointer_expression_p(expression expr)
POINTER EXPRESSION.
Definition: expression.c:4198
static transformer integer_power_to_transformer(entity e, expression arg1, expression arg2, transformer prec, bool is_internal)
Definition: expression.c:2444
static transformer process_bounds_for_divide(transformer tf, entity v, entity v1, int lb1, int ub1, entity v2, int lb2, int ub2)
Auxiliary function for non-affine operators such as divide, multiply, modulo...
Definition: expression.c:3141
static transformer addition_operation_to_transformer(entity v, expression e1, expression e2, transformer pre, bool addition_p, bool is_internal)
Type independent.
Definition: expression.c:438
transformer any_conditional_to_transformer(entity v, list args, transformer pre)
Take care of the returned value.
Definition: expression.c:5524
transformer simple_affine_to_transformer(entity e, Pvecteur a, bool is_internal)
INTEGER EXPRESSIONS.
Definition: expression.c:1167
static transformer integer_multiply_to_transformer(entity v, expression e1, expression e2, transformer prec, bool is_internal)
Assumes that e1 and e2 are integer expressions, i.e.
Definition: expression.c:1880
static transformer logical_binary_operation_to_transformer(entity v, call c, transformer pre, bool is_internal)
Definition: expression.c:3641
transformer any_expression_side_effects_to_transformer(expression e, transformer p, bool is_internal __attribute__((unused)))
The value of the expression is irrelevant, but its sub-expressions may generate a transformer.
Definition: expression.c:4845
static points_to_graph get_points_to_graph_from_statement(_UNUSED_ statement st)
semantic analysis: processing of expressions, with or without preconditions.
Definition: expression.c:93
transformer logical_not_to_transformer(entity v, list args, transformer pre)
returns the transformer associated to a C logical not, !, applied to an integer argument,...
Definition: expression.c:5571
transformer string_expression_to_transformer(entity v, expression rhs)
Definition: expression.c:3994
transformer safe_expression_to_transformer(expression exp, transformer pre)
Definition: expression.c:5307
static transformer generic_unary_operation_to_transformer(entity e, entity op, expression e1, transformer pre, bool is_internal)
Definition: expression.c:356
static transformer logical_constant_to_transformer(entity v, entity f)
Definition: expression.c:3583
static transformer integer_nullary_operation_to_transformer(entity e __attribute__((unused)), entity f __attribute__((unused)), transformer pre __attribute__((unused)), bool is_internal __attribute__((unused)))
FI: this function is no longer useful (11 August 2013)
Definition: expression.c:2856
transformer conditional_to_transformer(expression cond, expression te, expression fe, transformer pre, list ef)
FI: not too smart to start with the special case with no value returned, just side-effects....
Definition: expression.c:5488
static transformer pointer_binary_operation_to_transformer(entity e, expression expr, transformer pre, bool is_internal)
Definition: expression.c:4415
transformer transformer_logical_inequalities_add(transformer tf, entity v)
PROCESSING OF LOGICAL EXPRESSIONS.
Definition: expression.c:3569
transformer transformer_add_range_condition(transformer tf, expression c, transformer context, bool veracity)
Definition: expression.c:1147
static transformer modulo_of_a_negative_value_to_transformer(entity e, int lb1, int ub1, int lb2, int ub2)
e = [lb1,ub1] % [lb2,ub2] with ub1<=0
Definition: expression.c:1374
bool true_condition_wrt_precondition_p(expression c, transformer pre)
Definition: expression.c:5900
transformer safe_any_expression_side_effects_to_transformer(expression e, transformer p, bool is_internal)
Same as any_expression_side_effects_to_transformer() but effects are used to always generate a transf...
Definition: expression.c:4947
static list expression_to_points_to_sinks(_UNUSED_ expression e, _UNUSED_ points_to_graph in)
Definition: expression.c:100
transformer integer_expression_to_transformer(entity v, expression expr, transformer pre, bool is_internal)
Do check wrt to value mappings...
Definition: expression.c:3476
static transformer transformer_add_anded_conditions_updown(transformer pre, expression c1, expression c2, transformer context, bool veracity, bool upwards)
Definition: expression.c:727
static transformer integer_unary_operation_to_transformer(entity e, entity op, expression e1, transformer pre, bool is_internal)
Definition: expression.c:2880
bool eval_condition_wrt_precondition_p(expression c, transformer pre, bool veracity)
Definition: expression.c:5909
transformer lhs_expression_to_transformer(entity e, expression lhs, transformer pre)
This function deals with e1.e2 and e1->e2, not with simple references such as x or a[i].
Definition: expression.c:6262
static transformer expression_multiply_sizeof_to_transformer(entity v, expression e1, transformer prec, bool is_internal)
cut-and-pasted and adapted from multiply_to_transformer();
Definition: expression.c:2169
#define DEBUG_TRANSFORMER_ADD_CONDITION_INFORMATION_UPDOWN
HANDLING OF CONDITIONS.
Definition: expression.c:716
transformer float_expression_to_transformer(entity v, expression rhs, transformer pre, bool is_internal)
Definition: expression.c:4153
static transformer constant_to_transformer(entity v, expression rhs)
Definition: expression.c:645
transformer any_expressions_side_effects_to_transformer(list el, transformer p, bool is_internal)
same as any_expression_side_effects_to_transformer() but for a list of expressions
Definition: expression.c:4921
transformer assign_operation_to_transformer(entity val, expression lhs, expression rhs, transformer pre)
Returns an undefined transformer in case of failure.
Definition: expression.c:2737
transformer modulo_by_a_constant_to_transformer(entity v1, transformer prec, entity v2, int k)
Analyze v2 % k, with v2 constrainted by tf, assuming tf is a precondition.
Definition: expression.c:1481
void simplify_minmax_expression(expression e, transformer tr)
tries hard to simplify expression e if it is a min or a max operator, by evaluating it under precondi...
Definition: expression.c:5849
static transformer integer_binary_operation_to_transformer(entity e, entity op, expression e1, expression e2, transformer pre, bool is_internal)
Definition: expression.c:3274
transformer condition_to_transformer(expression cond, transformer pre, bool veracity)
To capture side effects and to add C twist for numerical conditions.
Definition: expression.c:5348
transformer logical_expression_to_transformer(entity v, expression rhs, transformer pre, bool is_internal)
Could be used to compute preconditions too.
Definition: expression.c:3938
static transformer transformer_add_call_condition_information_updown(transformer pre, entity op, list args, transformer context, bool veracity, bool upwards)
Definition: expression.c:882
static transformer min0_to_transformer(entity e, list args, transformer pre, bool is_internal)
Definition: expression.c:2720
#define DEBUG_TRANSFORMER_ADD_RELATION_INFORMATION
bool value_mappings_compatible_vector_p(Pvecteur iv)
transform a vector based on variable entities into a vector based on new value entities when possible...
Definition: mappings.c:924
void variables_to_new_values(Pvecteur v)
replace variables by new values which is necessary for equivalenced variables
Definition: mappings.c:1038
void upwards_vect_rename(Pvecteur v, transformer post)
Renaming of variables in v according to transformations occuring later.
Definition: mappings.c:1062
list semantics_expression_to_points_to_sinks(expression e)
Returns a list of cells.
Definition: points_to.c:112
list semantics_expression_to_points_to_sources(expression e)
Special wrapping for the semantics analyses.
Definition: points_to.c:94
void integer_value_and_precondition_to_integer_interval(entity, transformer, int *, int *)
Should be used by previous function, integer_expression_and_precondition_to_integer_interval()
Definition: utils.c:427
void integer_expression_and_precondition_to_integer_interval(expression, transformer, int *, int *)
Could be used for bool expressions too? Extended to any kind of expression?
Definition: utils.c:386
void expression_and_precondition_to_integer_interval(expression, transformer, int *, int *)
Evaluate expression e in context p, assuming that e is an integer expression.
Definition: utils.c:325
s1
Definition: set.c:247
#define ifdebug(n)
Definition: sg.c:47
#define intptr_t
Definition: stdint.in.h:294
#define MAX(x, y)
Definition: string.c:110
struct Scontrainte * succ
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
Definition: delay.c:253
#define abs(v)
Definition: syntax-local.h:48
transformer transformer_convex_hull(transformer t1, transformer t2)
transformer transformer_convex_hull(t1, t2): compute convex hull for t1 and t2; t1 and t2 are slightl...
Definition: convex_hull.c:216
transformer transformer_safe_apply(transformer tf, transformer pre)
Definition: transformer.c:1627
transformer transformer_safe_intersection(transformer t1, transformer t2)
Allocate a new transformer.
Definition: transformer.c:639
transformer transformer_normalize(transformer t, int level)
Eliminate (some) rational or integer redundancy.
Definition: transformer.c:932
transformer simple_addition_to_transformer(entity e, entity e1, entity e2, bool addition_p)
e and e1 and e2 are assumed to be values.
Definition: transformer.c:106
bool transformer_empty_p(transformer t)
If true is returned, the transformer certainly is empty.
Definition: transformer.c:2455
transformer transformer_safe_image_intersection(transformer t1, transformer t2)
Allocate a new transformer.
Definition: transformer.c:647
transformer relation_to_transformer(entity op, entity e1, entity e2, bool veracity)
e and f are assumed to be values.
Definition: transformer.c:139
transformer transformer_safe_combine_with_warnings(transformer tf1, transformer tf2)
Transformer tf1 and tf2 are supposed to be independent but they may interfere, for instance because s...
Definition: transformer.c:493
transformer simple_unary_minus_to_transformer(entity e, entity f)
Definition: transformer.c:65
transformer transformer_combine(volatile transformer t1, transformer t2)
transformer transformer_combine(transformer t1, transformer t2): compute the composition of transform...
Definition: transformer.c:238
transformer transformer_value_substitute(transformer t, entity e1, entity e2)
transformer transformer_value_substitute(transformer t, entity e1, entity e2): if e2 does not appear ...
Definition: transformer.c:1993
transformer transformer_apply(transformer tf, transformer pre)
transformer transformer_apply(transformer tf, transformer pre): apply transformer tf on precondition ...
Definition: transformer.c:1559
transformer transformer_range(transformer tf)
Return the range of relation tf in a newly allocated transformer.
Definition: transformer.c:714
transformer transformer_temporary_value_projection(transformer tf)
Definition: transformer.c:1149
transformer transformer_intersection(transformer t1, transformer t2)
tf is a new transformer that receives the constraints in t1 and t2.
Definition: transformer.c:600
transformer simple_equality_to_transformer(entity e, entity f, bool assignment)
e and f are assumed to be values, Type independent.
Definition: transformer.c:58
bool transformer_to_1D_lattice(entity v, transformer pre, Value *gcd_p, Value *c_p)
See if the equations in transformer "pre" constraint variable "v" by v = gcd x + c,...
Definition: transformer.c:2480
entity make_local_temporary_value_entity(type)
Definition: value.c:605
void add_sizeof_value(type)
For a given architecture, sizeof(t) is a constant.
Definition: value.c:1352
bool pointer_analyzed_p(void)
Definition: value.c:325
bool integer_analyzed_p(void)
Definition: value.c:300
bool analyzed_reference_p(reference)
FI: Nelson explains the motivation for can_be_constant_path_p() but I do not understand them.
Definition: value.c:518
bool analyzed_basic_p(basic)
The basic corresponds to one of the analyzed types.
Definition: value.c:337
bool analyzable_scalar_entity_p(entity)
The entity type is one of the analyzed types.
Definition: value.c:471
bool boolean_analyzed_p(void)
Definition: value.c:305
bool float_analyzed_p(void)
Definition: value.c:315
entity external_entity_to_new_value(entity)
Definition: value.c:1411
bool constant_path_analyzed_p(void)
Definition: value.c:330
bool string_analyzed_p(void)
Definition: value.c:310
entity entity_to_new_value(entity)
Definition: value.c:859
entity make_local_temporary_value_entity_with_basic(basic)
Definition: value.c:620
void reset_temporary_value_counter(void)
Definition: value.c:250
entity make_local_temporary_integer_value_entity(void)
Definition: value.c:629
entity type_to_sizeof_value(type)
Definition: value.c:899
bool entity_has_values_p(entity)
This function could be made more robust by checking the storage of e.
Definition: value.c:911
list modified_variables_with_values(void)
Return the list of all analyzed variables which are modified in the current module.
Definition: value.c:1094
entity entity_to_old_value(entity)
Definition: value.c:869
entity value_to_variable(entity)
Get the primitive variable associated to any value involved in a transformer.
Definition: value.c:1624
bool sizeof_value_entity_p(entity)
Definition: value.c:969
bool analyzed_type_p(type)
The type t is one of the analyzed types.
Definition: value.c:367
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define VECTEUR_NUL
DEFINITION DU VECTEUR NUL.
#define VECTEUR_NUL_P(v)
void * Variable
arithmetique is a requirement for vecteur, but I do not want to inforce it in all pips files....
Definition: vecteur-local.h:60
#define BASE_NULLE
MACROS SUR LES BASES.
Pvecteur vect_dup(Pvecteur v_in)
Pvecteur vect_dup(Pvecteur v_in): duplication du vecteur v_in; allocation de et copie dans v_out;.
Definition: alloc.c:51
Pvecteur vect_new(Variable var, Value coeff)
Pvecteur vect_new(Variable var,Value coeff): allocation d'un vecteur colineaire au vecteur de base va...
Definition: alloc.c:110
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78
Pvecteur vect_substract(Pvecteur v1, Pvecteur v2)
Pvecteur vect_substract(Pvecteur v1, Pvecteur v2): allocation d'un vecteur v dont la valeur est la di...
Definition: binaires.c:75
void vect_add_elem(Pvecteur *pvect, Variable var, Value val)
void vect_add_elem(Pvecteur * pvect, Variable var, Value val): addition d'un vecteur colineaire au ve...
Definition: unaires.c:72