PIPS
partial_eval.c
Go to the documentation of this file.
1 /*
2 
3  $Id: partial_eval.c 23065 2016-03-02 09:05:50Z 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 
28 /*
29  * Integer constants calculated by preconditions are replaced by their value.
30  * Expressions are evaluated to (ICOEF*SUBEXPR + ISHIFT) in order to perform
31  * some simplifications. When ICOEF==0, SUBEXPR must be undefined.
32  */
33 
34 /* Hypotheses pour l'implementation:
35 
36 Toute fonction d'evaluation partielle retourne eformat_undefined
37 lorsqu'elle n'a rien evalue (ex: lors d'un appel d'une fonction
38 externe).
39 
40 eformat.expr NE DOIT JAMAIS partager de structures avec le code. Par
41 contre, une expression detachee du code peut appartenir a eformat.expr.
42 
43 Lorsqu'une expression est detachee du code, il faut prendre garde a la
44 remplacer par expression_undefined. Sinon, le free (dans
45 regenerate_expression()) causera des degas!
46 
47 Si une information est ajoutee a eformat_undefined, alors l'expression
48 est RECOPIEE. Pourtant, eformat.simpler reste false et l'expression
49 d'origine n'est pas freee, car une seule information ne permet aucune
50 simplification. A partir de la prise en compte de la seconde
51 information, des qu'eformat est simplife', alors eformat.simpler
52 devient vrai. L'expression d'origine sera alors free'e lorsque
53 regenerate_expression().
54 
55 Des que l'evaluation n'est plus possible, il faut regenerer l'expression.
56 
57 Note FI: now NORMALIZE_EXPRESSION() is also used to simplify
58 expressions and sub-expressions in partial_eval_expression() because
59 automatic program transformations sometimes generate kind of stupid
60 code such as "i-i+1" or "512-1". When a simplification occurs, no
61 feedback is provided and the linearized version of the expression is
62 assumed "simpler". Hence, "simpler" now means "may be simpler". See
63 comments below in partial_eval_expression(). Also, I did not take time
64 to understand the invariant for expression allocation and free. I'm
65 very likely to have introduced memory leaks via the changes in
66 partial_eval_expression().
67 
68 Note FI: the interface is based on Psystemes instead of transformers,
69 which makes maintenance and evolution harder.
70  */
71 
72 #include <stdio.h>
73 #include <string.h>
74 
75 #include "genC.h"
76 #include "linear.h"
77 #include "ri.h"
78 #include "effects.h"
79 #include "text.h"
80 
81 #include "text-util.h"
82 #include "database.h"
83 #include "resources.h"
84 #include "control.h"
85 #include "ri-util.h"
86 #include "prettyprint.h"
87 #include "effects-util.h"
88 #include "pipsdbm.h"
89 #include "misc.h"
90 #include "properties.h"
91 
92 #include "effects-generic.h"
93 #include "effects-simple.h" /* for print_effects() */
94 #include "transformer.h"
95 #include "semantics.h" /* for module_to_value_mappings() */
96 
97 #include "arithmetique.h"
98 
99 #include "expressions.h"
100 
101 
103 /* when formating is useless (ie. = (1 * expr + 0)) */
104 
105 /* Set of enclosing loop indices
106  *
107  * This set is maintained to avoid useless partial evaluation of loop indices
108  * which are very unlikely to be partially evaluable. Loops with only one
109  * iteration can be removed by dead code elimination.
110  *
111  * This set is implemented as a list because the loop nest depth is expected
112  * small.
113  *
114  * It would be nice to take inductive variables into account. Their evaluation
115  * is quite long in ocean. We could use the loop transformer instead of the
116  * loop index to populate live_loop_indices. But it would be harder to regenerate
117  * the set when leaving the loop, unless a copy is made on entrance.
118  *
119  * A stack is not too attractive, as it should be all visited to make sure
120  * a variable is not a live loop index or inductive variable.
121  *
122  * A multiset might make loop exit easier, but each membership test will be
123  * longer.
124  */
125 
128 
130 {
131  pips_assert("set_live_loop_indices", live_loop_indices==list_undefined);
133 }
134 
136 {
137  /* The index set should be empty when leaving partial eval */
138  pips_assert("reset_live_loop_indices", ENDP(live_loop_indices));
139  if(!ENDP(live_loop_indices)) {
141  }
143 }
144 
146 {
147  pips_assert("set_live_loop_indices", live_loop_indices!=list_undefined);
149 }
150 
151 static bool live_loop_index_p(entity i)
152 {
153  pips_assert("set_live_loop_indices", live_loop_indices!=list_undefined);
155 }
156 
158 {
159  pips_assert("add_live_index",!live_loop_index_p(i));
161  CONS(ENTITY, i, NIL));
162 }
163 
165 {
166  pips_assert("set_live_loop_indices", live_loop_indices!=list_undefined);
168 }
169 
170 ␌
172 {
174  db_get_memory_resource(DBR_PROPER_EFFECTS, module_name, true));
175  pips_assert("init_use_proper_effects", !proper_rw_effects_undefined_p());
176 }
177 
178 /* returns proper effects associated to statement stmt */
180 {
181  effects fx;
182 
183  pips_assert("stmt is defined", stmt != statement_undefined);
184 
185  pips_debug(9,
186  "Look for effects for statement at %p (ordering %td, number %td):\n",
188 
189  fx = apply_statement_effects(fx_map, stmt);
190  ifdebug(5)
191  {
193  }
194 
195  return(fx);
196 }
197 
199 {
200  if(fx==effects_undefined)
201  pips_internal_error("effects undefined");
202 
203  MAPL(ftl, {
204  effect ft = EFFECT(CAR(ftl));
209  return(true);
210  }, effects_effects(fx));
211 
212  return(false);
213 }
214 
215 
217 {
219  db_get_memory_resource(DBR_PRECONDITIONS, module_name, true) );
220  pips_assert("init_use_preconditions",
222  if(get_debug_level()==9) {
224  }
225 }
226 
227 /*
228  cf. load_statement_transformer() in semantics/dbm_interface.c
229  */
231 {
232  transformer t;
233 
234  pips_assert("stmt_prec", stmt != statement_undefined);
235 
236  pips_debug(9,
237  "Look for preconditions for statement at %p (ordering %td, number %td):\n",
239 
241 
243 
244  /* pips_assert("stmt_prec", t != transformer_undefined);*/
245 
246  return(t==transformer_undefined ?
247  SC_UNDEFINED :
249 
250 }
251 
253 {
254  FILE * f =stderr;
256 
258 
259  HASH_MAP(k, v, {
260  fprintf(f, "\nFor statement at %p (ordering %td, number %td):\n",
261  k,
265  },
266  htp);
267 }
268 
270 {
271  /* should not require anything about expr */
272  return( ef1.expr == ef2.expr /* ie expression_eq(ef1.expr, ef2.expr) */
273  && ef1.icoef == ef2.icoef
274  && ef1.ishift == ef2.ishift );
275 }
276 
277 void print_eformat(eformat_t ef, char *name)
278 {
279  (void) printf("eformat %s = %d x EXPR + %d, %ssimpler, with EXPR:\n",
280  name, ef.icoef, ef.ishift, (ef.simpler ? "" : "NOT "));
282 }
283 
285 {
286  eformat_t ef;
287 
288  ef = partial_eval_expression(*ep, ps, fx);
289 
290  ifdebug(5)
291  print_eformat(ef, "before regenerate");
292 
293  regenerate_expression(&ef, ep);
294 
295  ifdebug(5) {
296  if(!expression_consistent_p(*ep)) {
297  pips_internal_error("bad evaluation");
298  }
299  else {
300  print_eformat(ef, "after regenerate");
301  }
302  }
303 }
304 
306 {
307  eformat_t ef;
308 
309  ef = partial_eval_expression(expr, ps, fx);
310 
312  ef.expr = expr;
313  }
314 
315  return(ef);
316 }
317 
319 {
320  eformat_t ef;
321  expression ne = e;
322  normalized n;
323 
326  n = expression_normalized(e);
327 
328  /* In case the expression is affine, use its affine form
329 
330  FI: it would be better to test if ne is really simpler than e: it
331  should contain fewer operators (1+1->2) or fewer references
332  (n->1).
333  */
334  if(normalized_linear_p(n)) {
335  Pvecteur pv = normalized_linear(n);
336  ne = make_vecteur_expression(pv);
337  ef = partial_eval_syntax(ne, ps, fx);
338  if(!ef.simpler /*&& !ef.icoef==0 && !ef.ishift==0*/) {
339  /* FI: it may be simpler because the simplification may be
340  performed by normalize_expression() */
341  ef.simpler = true;
342  if(expression_undefined_p(ef.expr) && ef.icoef!=0)
343  ef.expr = ne;
344  //ef.expr = ne;
345  //ef.icoef = 1;
346  //ef.ishift = 0;
347  }
348  }
349  else
350  ef = partial_eval_syntax(ne, ps, fx);
351 
352  return ef;
353 }
354 
356 {
357  eformat_t ef;
358  syntax s = expression_syntax(e);
359 
360  switch (syntax_tag(s)) {
361  case is_syntax_reference:
362  ef = partial_eval_reference(e, ps, fx);
363  break;
364  case is_syntax_range:
365  ef = eformat_undefined;
366  break;
367  case is_syntax_call:
368  ef = partial_eval_call_expression(e, ps, fx);
369  break;
370  case is_syntax_cast: {
371  cast c = syntax_cast(s);
372 
374  ef = eformat_undefined;
375  break;
376  }
379 
382  }
383  else if(get_bool_property("EVAL_SIZEOF")) {
384  type t = sizeofexpression_type(soe);
385  int tms = type_memory_size(t);
388  )
389  );
390  }
391  ef = eformat_undefined;
392  break;
393  }
394  case is_syntax_subscript: {
395  subscript sub = syntax_subscript(s);
397  for(list iter=subscript_indices(sub);!ENDP(iter);POP(iter))
399 
400  /*
401  MAPL(ce, {
402  partial_eval_expression_and_regenerate(&(EXPRESSION(CAR(ce))), ps, fx);
403  }, el);
404  */
405 
406  ef = eformat_undefined;
407  break;
408  }
409  case is_syntax_application: {
411 
413 
414  /*
415  MAPL(ce, {
416  partial_eval_expression_and_regenerate(&(EXPRESSION(CAR(ce))), ps, fx);
417  }, al);
418  */
419  ef = eformat_undefined;
420  break;
421  }
422  case is_syntax_va_arg:
423  ef = eformat_undefined;
424  break;
425  default:
426  pips_internal_error("case default");
427  abort();
428  }
429 
430  if (get_debug_level()==9)
431  print_eformat(ef, "after partial_eval_syntax");
432 
433  return(ef);
434 }
435 
437 {
438  reference r;
439  entity var;
440  Pbase base_min = BASE_UNDEFINED;
441 
442  pips_assert("partial_eval_reference",
445  var = reference_variable(r);
446 
447  if(reference_indices(r) != NIL) {
448  MAPL(li, {
449  expression expr = EXPRESSION(CAR(li));
450 
452  EXPRESSION_(CAR(li)) = expr;
453  }, reference_indices(r));
454 
455  debug(9, "partial_eval_reference", "Array elements not evaluated\n");
456  return(eformat_undefined);
457  }
458 
459  /* FI: this test may be wrong for enum variables? Does it matter?
460  what can you do with enum anyway? Well, they can be replaced by
461  their values */
462  if(!type_variable_p(entity_type(var)) ||
464  pips_debug(9, "Reference to a non-scalar-integer variable %s cannot be evaluated\n",
465  entity_name(var));
466  return(eformat_undefined);
467  }
468 
469  if (SC_UNDEFINED_P(ps)) {
470  pips_debug(9, "No precondition information\n");
471  pips_internal_error("Probably corrupted precondition");
472  return(eformat_undefined);
473  }
474 
475  if(entity_written_p(var, fx)) {
476  /* entity cannot be replaced */
477  debug(9, "partial_eval_reference",
478  "Write Reference to variable %s cannot be evaluated\n",
479  entity_name(var));
480  return(eformat_undefined);
481  }
482 
483  if(live_loop_index_p(var)) {
484  pips_debug(9, "Index %s cannot be evaluated\n", entity_name(var));
485  return(eformat_undefined);
486  }
487 
488  /* faire la Variable */
489  /* verification de la presence de la variable dans ps */
490  base_min = sc_to_minimal_basis(ps);
491  if(base_contains_variable_p(base_min, (Variable) var)) {
492  bool feasible;
493  Value min, max;
494  Psysteme ps1 = sc_dup(ps);
495 
496  /* feasible = sc_minmax_of_variable(ps1, (Variable) var, &min, &max); */
497  feasible = sc_minmax_of_variable2(ps1, (Variable) var, &min, &max);
498  if (! feasible) {
499  pips_user_warning("Not feasible system:"
500  " module contains some dead code.\n");
501  }
502  if ( value_eq(min,max) ) {
503  eformat_t ef;
504 
505  /* var is constant and has to be replaced */
506  ifdebug(9) {
507  pips_debug(9, "Constant to replace: \n");
508  print_expression(e);
509  }
510 
511  ef.icoef = 0;
512  ef.ishift = VALUE_TO_INT(min);
514  ef.simpler = true;
515  return(ef);
516 
517  /* new_expr=int_to_expression((int)min); */
518  /* replace expression_normalized(e) with
519  expression_normalized(new_expr) */
520  /* free_normalized(expression_normalized(e));
521  expression_normalized(e) = expression_normalized(new_expr);
522  expression_normalized(new_expr) = normalized_undefined; */
523 
524  /* replace expression_syntax(e) with
525  expression_syntax(new_expr) */
526  /*
527  free_syntax(expression_syntax((e)));
528  expression_syntax(e) = expression_syntax(new_expr);
529  expression_syntax(new_expr) = syntax_undefined;
530 
531  free_expression(new_expr);
532 
533 
534 
535 
536  if ( get_debug_level() == 9) {
537  debug(9, "partial_eval_reference",
538  "Constant replaced by expression: \n");
539  print_to_expressionession(e);
540  expression_consistent_p(e);
541  pips_assert("partial_eval_reference",
542  syntax_call_p(expression_syntax(e)));
543  } */
544  }
545  /* return(entity_initial(call_function(syntax_call(expression_syntax(e)))));
546  */
547  return(eformat_undefined);
548  }
549  base_rm(base_min);
550  return(eformat_undefined);
551 }
552 
554 {
555  //list le = list_undefined;
556  eformat_t ef = partial_eval_call(ca, ps, fx);
557 
558  pips_assert("ca is a defined call", ca!= call_undefined);
559 
560  /* FI: if the call is an operator, it is not part of the
561  simplification; e.g. "3+5;" */
562  /*
563  for(le=call_arguments(ca); !ENDP(le); POP(le)) {
564  expression exp = EXPRESSION(CAR(le));
565 
566  partial_eval_expression_and_regenerate(&exp, ps, fx);
567  EXPRESSION_(CAR(le))= exp;
568  }
569  */
570  regenerate_call(&ef, ca);
571 }
572 
573 
575 {
576  entity func;
577  value vinit;
578  eformat_t ef;
579  func = call_function(ec);
580  vinit = entity_initial(func);
581 
582  switch (value_tag(vinit)) {
583  case is_value_intrinsic:
584  case is_value_unknown: {
585  /* it might be an intrinsic function */
586  cons *la = call_arguments(ec);
587  size_t nbargs = gen_length(la);
588  switch(nbargs) {
589  case 1:
590  ef = partial_eval_unary_operator(func, la, ps, fx);break;
591  case 2:
592  ef = partial_eval_binary_operator(func, la, ps, fx);break;
593  default:
594  {
596  ef = eformat_undefined;
597  }
598  }
599  } break;
600  case is_value_constant:
601  if(integer_constant_p(func, &ef.ishift)) {
602  ef.icoef = 0;
604  ef.simpler = false;
605  }
606  else ef = eformat_undefined;
607  break;
608  case is_value_symbolic:
609  if(integer_symbolic_constant_p(func, &ef.ishift)) {
610  ef.icoef = 0;
612  ef.simpler = true;
613  }
614  else ef = eformat_undefined;
615  break;
616  case is_value_code:
617  {
618  /* FI: The actual aruments are not partially evaluated?
619  * SG: no it's not, I fixed this
620  *
621  * FI: Actually, the parameter mode should be checked. And the
622  * actual effects.
623  *
624  * Note FI: the result obtained for the call to fx in
625  * Transformations/eval.c is correct, but I do not understand
626  * why. Actual parameters must be evaluated somewhere else.
627  */
628  list ce;
629  for(ce = call_arguments(ec); !ENDP(ce); POP(ce))
630  {
631  expression eparam = EXPRESSION(CAR(ce));
632  if(c_language_module_p(func)) {
633  /* value passing */
635  EXPRESSION_(CAR(ce)) = eparam;
636  }
637  else if(fortran_language_module_p(func)) {
638  /* the partial evaluation could be further improved by
639  checking if there is a write effect on the
640  corresponding formal parameter */
641  if(false && expression_reference_p(eparam))
642  /* This is dealt for using fx when dealing with a
643  reference */
644  ; // in doubt, do nothing
645  else {
647  EXPRESSION_(CAR(ce)) = eparam;
648  }
649  }
650  else {
651  pips_internal_error("Unexpected programming language");
652  }
653  }
654 
655  ef = eformat_undefined;
656  } break;
657  default:
658  pips_internal_error("Default case reached.");
659  ef = eformat_undefined;
660  }
661  return ef;
662 }
663 
665 {
666  call ec;
667  //entity func;
668  //value vinit;
669  eformat_t ef;
670 
671  pips_assert("The expression is a call",
674 
675  ef = partial_eval_call(ec, ps,fx);
676 
677  return ef;
678 }
679 
681 {
682  eformat_t ef;
683  expression *sub_ep;
684 
685  pips_assert("one argument", gen_length(la)==1);
686  sub_ep = /*&EXPRESSION(CAR(la));*/ (expression*) REFCAR(la);
687 
688  if (ENTITY_UNARY_MINUS_P(func)) {
689  ef = partial_eval_expression_and_copy(*sub_ep, ps, fx);
690 
691  if(ef.icoef==0
692  || ((ef.icoef<0 || ef.icoef>1)
693  && (ef.ishift<=0))
694  ) {
695  ef.simpler= true;
696  }
697 
698  ef.icoef= -(ef.icoef);
699  ef.ishift= -(ef.ishift);
700  }
701  else if(ENTITY_ADDRESS_OF_P(func)) {
702  ef = partial_eval_expression_and_copy(*sub_ep, ps, fx);
703  if(ef.icoef!=0) // it means we should not generate a constant now
705  ef = eformat_undefined;
706  }
707  else {
708  /* operator can be a pre/post inc/dec C operator */
710  ef = eformat_undefined;
711  }
712  return(ef);
713 }
714 
715 
716 #define PERFORM_ADDITION 1
717 #define PERFORM_SUBTRACTION 2
718 #define PERFORM_MULTIPLICATION 3
719 #define PERFORM_DIVISION 4
720 #define PERFORM_C_DIVISION 14
721 #define PERFORM_POWER 5
722 #define PERFORM_MODULO 6
723 #define PERFORM_C_MODULO 16
724 #define PERFORM_MINIMUM 7
725 #define PERFORM_MAXIMUM 8
726 
728  expression *ep2,
729  Psysteme ps,
730  effects fx)
731 {
732  eformat_t ef, ef1, ef2;
733 
734  ef1 = partial_eval_expression_and_copy(*ep1, ps, fx);
735  ef2 = partial_eval_expression_and_copy(*ep2, ps, fx);
736 
737  if(ef1.icoef==0 && ef2.icoef==0) {
738  ef.icoef=0;
740  ef.ishift= ef1.ishift * ef2.ishift;
741  ef.simpler= true;
742  }
743  else if(ef1.icoef!=0 && ef2.icoef!=0) {
744  if(ef2.icoef!=1 && ef2.ishift==0) {
745  expression *ep;
746  /* exchange ef1 and ef2 (see later) */
747  ef=ef2; ef2=ef1; ef1=ef; ef= eformat_undefined;
748  ep=ep2; ep2=ep1; ep1=ep;
749  }
750  if(ef1.icoef!=1 && ef1.ishift==0) {
751  ef.simpler= ef1.simpler;
752  ef.icoef= ef1.icoef;
753  regenerate_expression(&ef2, ep2);
755  ef1.expr, *ep2);
756  ef.ishift= 0;
757  }
758  else { /* cannot optimize */
759  regenerate_expression(&ef1, ep1);
760  regenerate_expression(&ef2, ep2);
761 
762  ef= eformat_undefined;
763  }
764  }
765  else {
766  if(ef2.icoef==0) {
767  expression *ep;
768  /* exchange ef1 and ef2 (see later) */
769  ef=ef2; ef2=ef1; ef1=ef; ef= eformat_undefined;
770  ep=ep2; ep2=ep1; ep1=ep;
771  }
772  /* here we know that ef1.ecoef==0 and ef2.ecoef!=0 */
773  if(ef1.ishift==0) {
774  ef.icoef= 0;
776  ef.ishift= 0;
777  ef.simpler= true;
778  regenerate_expression(&ef2, ep2);
779  }
780  else {
781  ef.icoef= ef1.ishift * ef2.icoef;
782  ef.expr= ef2.expr;
783  ef.ishift= ef1.ishift * ef2.ishift;
784  ef.simpler= (ef1.ishift==1 || ef2.icoef!=1
785  || ef1.simpler || ef2.simpler);
786  }
787  }
788 
789  return ef;
790 }
791 
793  expression *ep1,
794  expression *ep2,
795  Psysteme ps,
796  effects fx)
797 {
799  /* Automatic tools sometimes generate source code like "i - i" */
800  /* Could be improved with a commutative_expression_equal_p() if
801  cases arise */
802  if(expression_equal_p(*ep1, *ep2)) {
803  if(token==PERFORM_SUBTRACTION) {
804  ef.simpler = true;
805  ef.expr = expression_undefined; //int_to_expression(0);
806  ef.icoef = 0;
807  ef.ishift = 0;
808  }
809  else if(token==PERFORM_ADDITION) {
810  ef.simpler = true;
811  /* FI: no idea of the expression should be copied or not, let's
812  play safe. */
813  /* Here we should go down to see if *ep1 can be partially
814  evaluated */
815  eformat_t ef1 = partial_eval_expression_and_copy(*ep1, ps, fx);
816  ef.expr = ef1.expr;
817  ef.icoef = 2*ef1.icoef;
818  ef.ishift = 2*ef1.ishift;
819  /* FI: here I should get rid of ef1... */
820  }
821  else {
822  pips_internal_error("Ill. token %d\n", token);
823  }
824  }
825  else {
826  eformat_t ef1, ef2;
827 
828  ef1 = partial_eval_expression_and_copy(*ep1, ps, fx);
829  ef2 = partial_eval_expression_and_copy(*ep2, ps, fx);
830 
831  /* generate ef.icoef and ef.expr */
832  if( (ef1.icoef==ef2.icoef || ef1.icoef==-ef2.icoef)
833  && (ef1.icoef<-1 || ef1.icoef>1) ) {
834  /* factorize icoef */
835  ef.simpler=true;
836  if( (token==PERFORM_ADDITION && ef1.icoef==ef2.icoef)
837  || (token==PERFORM_SUBTRACTION && ef1.icoef==-ef2.icoef) ) {
838  /* addition */
840  ef1.expr,
841  ef2.expr);
842  ef.icoef= ef1.icoef;
843  }
844  else if( (ef1.icoef>1)
845  && (token==PERFORM_SUBTRACTION ? (ef2.icoef>0) : (ef2.icoef<0)) ) {
846  /* substraction e1-e2 */
848  ef1.expr,
849  ef2.expr);
850  ef.icoef= ef1.icoef;
851  }
852  else {
853  /* substraction e2-e1 */
855  ef2.expr,
856  ef1.expr);
857  ef.icoef= -ef1.icoef;
858  }
859  }
860  else if(ef1.icoef!=0 && ef2.icoef!=0) {
861  int c1 = ef1.icoef;
862  int c2 = (token==PERFORM_SUBTRACTION ? -ef2.icoef : ef2.icoef);
863  expression e1= generate_monome((c1>0 ? c1: -c1), ef1.expr);
864  expression e2= generate_monome((c2>0 ? c2: -c2), ef2.expr);
865 
866  /* generate without factorize, but for -1? */
867  ef.simpler= (ef1.simpler || ef2.simpler); /* not precise ?? */
868  if(c1*c2>0) {
870  e1, e2);
871  ef.icoef= (c1>0 ? 1 : -1);
872  }
873  else if(c1>0) {
875  e1, e2);
876  ef.icoef= 1;
877  }
878  else {
880  e2, e1);
881  ef.icoef= 1;
882  }
883  }
884  else {
885  ef.simpler= (ef1.simpler || ef2.simpler);
886  if(ef1.icoef==0) {
887  /* CA (9/9/97) condition <0 added in order to simplify
888  also expression like (J)+(-1) in (J-1) */
889  if(ef1.ishift<=0)
890  ef.simpler=true;
891  ef.expr=ef2.expr;
892  ef.icoef=(token==PERFORM_SUBTRACTION ? -ef2.icoef : ef2.icoef);
893  }
894  else if(ef2.icoef==0) {
895  /* FI: simplification i++ + 0? I do not understand Corinne's
896  code above. ef.ishift is generated below. I force simpler
897  because ef2.icoef==0 can result from a simplification */
898  ef.expr = ef1.expr;
899  ef.icoef = ef1.icoef;
900  ef.simpler=true;
901  }
902  else {
903  if(ef2.ishift<=0)
904  ef.simpler=true;
905  ef.expr=ef1.expr;
906  ef.icoef=ef1.icoef;
907  }
908  }
909 
910  /* generate ef.ishift */
911  if ((ef1.icoef==0 || ef1.ishift!=0)
912  && (ef2.icoef==0 || ef2.ishift!=0))
913  {
914  /* simplify shifts */
915  ef.simpler= true;
916  }
917 
918  ef.ishift= (token==PERFORM_SUBTRACTION ?
919  ef1.ishift-ef2.ishift : ef1.ishift+ef2.ishift);
920  }
921  return ef;
922 }
923 
925  expression *ep2,
926  Psysteme ps,
927  effects fx)
928 {
929  eformat_t ef;
930 
932  ep1, ep2, ps, fx);
933 
934  return ef;
935 }
936 
938  expression *ep2,
939  Psysteme ps,
940  effects fx)
941 {
943  basic b1 = basic_of_expression(*ep1);
944  basic b2 = basic_of_expression(*ep2);
945  if( !basic_pointer_p(b1) && !basic_pointer_p(b2) )
946  {
947  ef = partial_eval_plus_operator(ep1,ep2,ps,fx);
948  }
949  else {
952  }
953  free_basic(b1);
954  free_basic(b2);
955 
956  return ef;
957 }
958 
960  expression *ep2,
961  Psysteme ps,
962  effects fx)
963 {
964  eformat_t ef;
965 
967  ep1, ep2, ps, fx);
968 
969  return ef;
970 }
971 
973  expression *ep2,
974  Psysteme ps,
975  effects fx)
976 {
978  basic b1 = basic_of_expression(*ep1);
979  basic b2 = basic_of_expression(*ep2);
980  if( !basic_pointer_p(b1) && !basic_pointer_p(b2) )
981  {
982  ef = partial_eval_minus_operator(ep1,ep2,ps,fx);
983  }
984  else {
987  }
988  free_basic(b1);
989  free_basic(b2);
990  return ef;
991 }
992 
994  expression *ep1,
995  expression *ep2,
996  Psysteme ps,
997  effects fx)
998 {
999  eformat_t ef, ef1, ef2;
1000 
1001  ef1 = partial_eval_expression_and_copy(*ep1, ps, fx);
1002  ef2 = partial_eval_expression_and_copy(*ep2, ps, fx);
1003 
1004  if( ef2.icoef==0 && ef2.ishift == 0 )
1005  user_error("partial_eval_div_or_mod_operator",
1006  "division by zero!\n");
1007  if( token==PERFORM_DIVISION && ef2.icoef==0
1008  && (ef1.ishift % ef2.ishift)==0
1009  && (ef1.icoef % ef2.ishift)==0 ) {
1010  /* integer division does NOT commute with in any */
1011  /* multiplication -> only performed if "exact" */
1012  ef.simpler= true;
1013  ef.icoef= ef1.icoef / ef2.ishift;
1014  ef.ishift= ef1.ishift / ef2.ishift;
1015  ef.expr= ef1.expr;
1016  }
1017  else if(ef1.icoef==0 && ef2.icoef==0) {
1018  ef.simpler= true;
1019  ef.icoef= 0;
1021  if (token==PERFORM_DIVISION) { /* refer to Fortran77 chap 6.1.5 */
1022  /* FI->SG: FORTRAN_DIV, SIGN_EQ, FORTRAN_MOD,... have been left in
1023  transformations-local.h when this code was moved into
1024  expressions. I haven't checked if they are used
1025  elsewhere. Could the expression library not dependent on
1026  transformations? */
1027  ef.ishift= FORTRAN_DIV(ef1.ishift, ef2.ishift);
1028  }
1029  else {
1030  /* FI: C and Fortran modulo and division operators seem in fact
1031  equivalent, using negative modulo to maintain the equation
1032 
1033  a == (a/b)*b+a%b
1034 
1035  instead of a positive remainder, i.e. modulo.
1036  */
1037  if(token==PERFORM_MODULO)
1038  ef.ishift= FORTRAN_MOD(ef1.ishift, ef2.ishift);
1039  else if(token==PERFORM_C_MODULO)
1040  ef.ishift= C_MODULO(ef1.ishift, ef2.ishift);
1041  else
1042  pips_internal_error("Unexpected tocken");
1043  }
1044  }
1045  else {
1046  regenerate_expression(&ef1, ep1);
1047  regenerate_expression(&ef2, ep2);
1048  ef= eformat_undefined;
1049  }
1050  return ef;
1051 }
1052 
1054  expression *ep2,
1055  Psysteme ps,
1056  effects fx)
1057 {
1058  eformat_t ef;
1059 
1061  ep1, ep2, ps, fx);
1062 
1063  return ef;
1064 }
1065 
1067  expression *ep2,
1068  Psysteme ps,
1069  effects fx)
1070 {
1071  eformat_t ef;
1072 
1074  ep1, ep2, ps, fx);
1075 
1076  return ef;
1077 }
1078 
1080  expression *ep2,
1081  Psysteme ps,
1082  effects fx)
1083 {
1084  eformat_t ef;
1085 
1087  ep1, ep2, ps, fx);
1088 
1089  return ef;
1090 }
1091 
1093  expression *ep1,
1094  expression *ep2,
1095  Psysteme ps,
1096  effects fx)
1097 {
1098  eformat_t ef;
1099  bool ok = false;
1100  {
1103  intptr_t lb,ub;
1104  if(precondition_minmax_of_expression(fake,tr,&lb,&ub))
1105  {
1106  if(lb>=0) /* ep1-ep2 >= 0 -> min(ep1,ep2) == ep2 and max(ep1,ep2) == ep1 */
1107  {
1108  ef= partial_eval_expression_and_copy(*(token==PERFORM_MAXIMUM?ep1:ep2),ps,fx);
1109  ef.simpler=true;
1110  ok=true;
1111  }
1112  else if(ub <= 0 ) /* ep1-ep2 <= 0 -> min(ep1,ep2) == ep1 and max(ep1,ep2) == ep2 */
1113  {
1114  ef= partial_eval_expression_and_copy(*(token==PERFORM_MAXIMUM?ep2:ep1),ps,fx);
1115  ef.simpler=true;
1116  ok=true;
1117  }
1118  }
1119  }
1120 
1121  if(!ok) {
1122  eformat_t ef1, ef2;
1123  ef1 = partial_eval_expression_and_copy(*ep1, ps, fx);
1124  ef2 = partial_eval_expression_and_copy(*ep2, ps, fx);
1125 
1126  if( ef1.icoef == 0 && ef2.icoef == 0 ) {
1127  ef.icoef = 0;
1128  ef.ishift = (token==PERFORM_MAXIMUM)? MAX(ef1.ishift,ef2.ishift):
1129  MIN(ef1.ishift,ef2.ishift);
1131  ef.simpler = true;
1132  }
1133  else {
1134  regenerate_expression(&ef1, ep1);
1135  regenerate_expression(&ef2, ep2);
1136  ef = eformat_undefined;
1137  }
1138  }
1139 
1140  return ef;
1141 }
1142 
1144  expression *ep2,
1145  Psysteme ps,
1146  effects fx)
1147 {
1148  eformat_t ef;
1149 
1151  ep1, ep2, ps, fx);
1152 
1153  return ef;
1154 }
1155 
1157  expression *ep2,
1158  Psysteme ps,
1159  effects fx)
1160 {
1161  eformat_t ef;
1162 
1164  ep1, ep2, ps, fx);
1165 
1166  return ef;
1167 }
1168 
1170  expression *ep2,
1171  Psysteme ps,
1172  effects fx)
1173 {
1174  eformat_t ef, ef1, ef2;
1175 
1176  ef1 = partial_eval_expression_and_copy(*ep1, ps, fx);
1177  ef2 = partial_eval_expression_and_copy(*ep2, ps, fx);
1178 
1179  if( ef1.icoef == 0 && ef2.icoef == 0 && ef2.ishift >= 0) {
1180  ef.icoef = 0;
1181  ef.ishift = ipow(ef1.ishift, ef2.ishift);
1183  ef.simpler = true;
1184  }
1185  else {
1186  regenerate_expression(&ef1, ep1);
1187  regenerate_expression(&ef2, ep2);
1188  ef = eformat_undefined;
1189  }
1190 
1191  return ef;
1192 }
1193 
1194 /* FI: a better job could be done by distinguishing between the
1195  different kinds of operators. For instance "a+=0" or "b*=1;" could
1196  be simplified. For the time being, we simplify the two
1197  sub-expressions but not the current expression. */
1199  expression *ep2,
1200  Psysteme ps,
1201  effects fx)
1202 {
1203  eformat_t ef, ef1, ef2;
1204 
1205  /* You do not want to change "n = 1; n = 1;" into n = 1; 1 = 1;" */
1206  if(!(expression_reference_p(*ep1)
1208  ef1 = partial_eval_expression_and_copy(*ep1, ps, fx);
1209  regenerate_expression(&ef1, ep1);
1210  }
1211 
1212  ef2 = partial_eval_expression_and_copy(*ep2, ps, fx);
1213  regenerate_expression(&ef2, ep2);
1214 
1215  ef = eformat_undefined;
1216 
1217  return ef;
1218 }
1219 
1220 static struct perform_switch {
1223 } binary_operator_switch[] = {
1245  {0 , 0}
1246 };
1247 
1249  cons *la,
1250  Psysteme ps,
1251  effects fx)
1252 {
1253  eformat_t ef;
1254  expression *ep1, *ep2;
1255  int i = 0;
1256  eformat_t (*binary_partial_eval_operator)(expression *,
1257  expression *,
1258  Psysteme,
1259  effects) = 0;
1260 
1261  pips_assert("partial_eval_binary_operator", gen_length(la)==2);
1262  ep1= (expression*) REFCAR(la);
1263  ep2= (expression*) REFCAR(CDR(la));
1264 
1265  while (binary_operator_switch[i].operator_name!=NULL) {
1266  if (strcmp(binary_operator_switch[i].operator_name,
1267  entity_local_name(func))==0) {
1268  binary_partial_eval_operator =
1270  break;
1271  }
1272  i++;
1273  }
1274 
1275  if (binary_partial_eval_operator!=0)
1276  ef = binary_partial_eval_operator (ep1, ep2, ps, fx);
1277  else {
1280  ef = eformat_undefined;
1281  }
1282  /* some more optimization if a neutral element has been generated */
1283  entity neutral = operator_neutral_element(func);
1284  if(!entity_undefined_p(neutral)) {
1285  if(same_entity_p(expression_to_entity(*ep1),neutral)) {
1286  ef=partial_eval_expression(*ep2,ps,fx);
1287  if(!ef.simpler) /*use some partial eval dark magic */
1288  {
1289  ef.simpler=true;
1290  ef.icoef=1;
1291  ef.expr=*ep2;
1292  }
1293  }
1294  else if(same_entity_p(expression_to_entity(*ep2),neutral)) {
1295  ef=partial_eval_expression(*ep1,ps,fx);
1296  if(!ef.simpler) /*use some partial eval dark magic */
1297  {
1298  ef.simpler=true;
1299  ef.icoef=1;
1300  ef.expr=*ep1;
1301  }
1302  }
1303  }
1304 
1305  return ef;
1306 }
1307 
1309  cons *la,
1310  Psysteme ps,
1311  effects fx)
1312 {
1313  eformat_t ef, ef1, ef2;
1314  expression *ep1, *ep2;
1315  int token= -1;
1316 
1317  pips_assert("partial_eval_binary_operator", gen_length(la)==2);
1318  ep1= (expression*) REFCAR(la);
1319  ep2= (expression*) REFCAR(CDR(la));
1320 
1321  if (strcmp(entity_local_name(func), MINUS_OPERATOR_NAME) == 0) {
1322  token = PERFORM_SUBTRACTION;
1323  }
1324  else if (strcmp(entity_local_name(func), PLUS_OPERATOR_NAME) == 0) {
1325  token = PERFORM_ADDITION;
1326  }
1327  else if (strcmp(entity_local_name(func), MULTIPLY_OPERATOR_NAME) == 0) {
1328  token = PERFORM_MULTIPLICATION;
1329  }
1330  else if (strcmp(entity_local_name(func), DIVIDE_OPERATOR_NAME) == 0) {
1331  /* FI: The C divide operator may be defined differently for negative
1332  integers */
1333  token = PERFORM_DIVISION;
1334  }
1335  else if (strcmp(entity_local_name(func), MODULO_OPERATOR_NAME) == 0) {
1336  token = PERFORM_MODULO;
1337  }
1338  else if (strcmp(entity_local_name(func), C_MODULO_OPERATOR_NAME) == 0) {
1339  /* FI: The C modulo operator may be defined differently for negative
1340  integers */
1341  token = PERFORM_MODULO;
1342  }
1343 
1344  if ( token==PERFORM_ADDITION || token==PERFORM_SUBTRACTION ) {
1345  ef1 = partial_eval_expression_and_copy(*ep1, ps, fx);
1346  ef2 = partial_eval_expression_and_copy(*ep2, ps, fx);
1347 
1348  /* generate ef.icoef and ef.expr */
1349  if( (ef1.icoef==ef2.icoef || ef1.icoef==-ef2.icoef)
1350  && (ef1.icoef<-1 || ef1.icoef>1) ) {
1351  /* factorize */
1352  ef.simpler=true;
1353  if( (token==PERFORM_ADDITION && ef1.icoef==ef2.icoef)
1354  || (token==PERFORM_SUBTRACTION && ef1.icoef==-ef2.icoef) ) {
1355  /* addition */
1357  ef1.expr,
1358  ef2.expr);
1359  ef.icoef= ef1.icoef;
1360  }
1361  else if( (ef1.icoef>1)
1362  && (token==PERFORM_SUBTRACTION ? (ef2.icoef>0) : (ef2.icoef<0)) ) {
1363  /* substraction e1-e2 */
1365  ef1.expr,
1366  ef2.expr);
1367  ef.icoef= ef1.icoef;
1368  }
1369  else {
1370  /* substraction e2-e1 */
1372  ef2.expr,
1373  ef1.expr);
1374  ef.icoef= -ef1.icoef;
1375  }
1376  }
1377  else if(ef1.icoef!=0 && ef2.icoef!=0) {
1378  int c1 = ef1.icoef;
1379  int c2 = (token==PERFORM_SUBTRACTION ? -ef2.icoef : ef2.icoef);
1380  expression e1= generate_monome((c1>0 ? c1: -c1), ef1.expr);
1381  expression e2= generate_monome((c2>0 ? c2: -c2), ef2.expr);
1382  /* generate without factorize */
1383  ef.simpler= (ef1.simpler || ef2.simpler); /* not precise ?? */
1384  if(c1*c2>0) {
1386  e1, e2);
1387  ef.icoef= (c1>0 ? 1 : -1);
1388  }
1389  else if(c1>0) {
1391  e1, e2);
1392  ef.icoef= 1;
1393  }
1394  else {
1396  e2, e1);
1397  ef.icoef= 1;
1398  }
1399  }
1400  else {
1401  ef.simpler= (ef1.simpler || ef2.simpler);
1402  if(ef1.icoef==0) {
1403  if(ef1.ishift==0) ef.simpler=true;
1404  ef.expr=ef2.expr;
1405  ef.icoef=(token==PERFORM_SUBTRACTION ? -ef2.icoef : ef2.icoef);
1406  }
1407  else {
1408  if(ef2.ishift==0) ef.simpler=true;
1409  ef.expr=ef1.expr;
1410  ef.icoef=ef1.icoef;
1411  }
1412  }
1413 
1414  /* generate ef.ishift */
1415  if ( (ef1.icoef==0 || ef1.ishift!=0)
1416  && (ef2.icoef==0 || ef2.ishift!=0) ) {
1417  /* simplify shifts */
1418  ef.simpler= true;
1419  }
1420  ef.ishift= (token==PERFORM_SUBTRACTION ?
1421  ef1.ishift-ef2.ishift : ef1.ishift+ef2.ishift);
1422  }
1423  else if( token==PERFORM_MULTIPLICATION ) {
1424  ef1 = partial_eval_expression_and_copy(*ep1, ps, fx);
1425  ef2 = partial_eval_expression_and_copy(*ep2, ps, fx);
1426 
1427  if(ef1.icoef==0 && ef2.icoef==0) {
1428  ef.icoef=0;
1430  ef.ishift= ef1.ishift * ef2.ishift;
1431  ef.simpler= true;
1432  }
1433  else if(ef1.icoef!=0 && ef2.icoef!=0) {
1434  if(ef2.icoef!=1 && ef2.ishift==0) {
1435  expression *ep;
1436  /* exchange ef1 and ef2 (see later) */
1437  ef=ef2; ef2=ef1; ef1=ef; ef= eformat_undefined;
1438  ep=ep2; ep2=ep1; ep1=ep;
1439  }
1440  if(ef1.icoef!=1 && ef1.ishift==0) {
1441  ef.simpler= ef1.simpler;
1442  ef.icoef= ef1.icoef;
1443  regenerate_expression(&ef2, ep2);
1445  ef1.expr, *ep2);
1446  ef.ishift= 0;
1447  }
1448  else { /* cannot optimize */
1449  regenerate_expression(&ef1, ep1);
1450  regenerate_expression(&ef2, ep2);
1451 
1452  ef= eformat_undefined;
1453  }
1454  }
1455  else {
1456  if(ef2.icoef==0) {
1457  expression *ep;
1458  /* exchange ef1 and ef2 (see later) */
1459  ef=ef2; ef2=ef1; ef1=ef; ef= eformat_undefined;
1460  ep=ep2; ep2=ep1; ep1=ep;
1461  }
1462  /* here we know that ef1.ecoef==0 and ef2.ecoef!=0 */
1463  if(ef1.ishift==0) {
1464  ef.icoef= 0;
1466  ef.ishift= 0;
1467  ef.simpler= true;
1468  regenerate_expression(&ef2, ep2);
1469  }
1470  else {
1471  ef.icoef= ef1.ishift * ef2.icoef;
1472  ef.expr= ef2.expr;
1473  ef.ishift= ef1.ishift * ef2.ishift;
1474  ef.simpler= (ef1.ishift==1 || ef2.icoef!=1
1475  || ef1.simpler || ef2.simpler);
1476  }
1477  }
1478  }
1479  else if(token==PERFORM_DIVISION || token==PERFORM_MODULO) {
1480  ef1 = partial_eval_expression_and_copy(*ep1, ps, fx);
1481  ef2 = partial_eval_expression_and_copy(*ep2, ps, fx);
1482 
1483  if( ef2.icoef==0 && ef2.ishift == 0 )
1484  user_error("partial_eval_binary_operator",
1485  "division by zero!\n");
1486  if( token==PERFORM_DIVISION && ef2.icoef==0
1487  && (ef1.ishift % ef2.ishift)==0
1488  && (ef1.icoef % ef2.ishift)==0 ) {
1489  /* integer division does NOT commute with in any */
1490  /* multiplication -> only performed if "exact" */
1491  ef.simpler= true;
1492  ef.icoef= ef1.icoef / ef2.ishift;
1493  ef.ishift= ef1.ishift / ef2.ishift;
1494  ef.expr= ef1.expr;
1495  }
1496  else if(ef1.icoef==0 && ef2.icoef==0) {
1497  ef.simpler= true;
1498  ef.icoef= 0;
1500  if (token==PERFORM_DIVISION) { /* refer to Fortran77 chap 6.1.5 */
1501  ef.ishift= FORTRAN_DIV(ef1.ishift, ef2.ishift);
1502  }
1503  else { /* tocken==PERFORM_MODULO */
1504  ef.ishift= FORTRAN_MOD(ef1.ishift, ef2.ishift);
1505  }
1506  }
1507  else {
1508  regenerate_expression(&ef1, ep1);
1509  regenerate_expression(&ef2, ep2);
1510  ef= eformat_undefined;
1511  }
1512  }
1513  else {
1516  ef= eformat_undefined;
1517  }
1518  return(ef);
1519 }
1520 
1521 /* in order to regenerate expression from eformat.;
1522  *
1523  * optimized so that it can be called for any compatible ef and *ep;
1524  * result in *ep.
1525  */
1527 {
1529  /* nothing to do because expressions are the same */
1530  }
1531  else if(!get_bool_property("PARTIAL_EVAL_ALWAYS_SIMPLIFY") && !efp->simpler) {
1532  /* simply free efp->expr */
1533  /* ******commented out for debug******* */
1534  //free_expression(efp->expr);
1535  efp->expr= expression_undefined; /* useless */
1536  }
1537  else {
1538  expression tmp_expr;
1539 
1540  /* *ep must be freed */
1541  /* ?? ******commented out for debug******* */
1542  /* free_expression(*ep); */
1543 
1544  if(efp->icoef != 0) {
1545  /* check */
1546  pips_assert("regenerate_expression",
1547  efp->expr != expression_undefined);
1548 
1549  if(efp->icoef == 1) {
1550  tmp_expr= efp->expr;
1551  }
1552  else if(efp->icoef == -1) {
1553  /* generate unary_minus */
1555  efp->expr);
1556  }
1557  else {
1558  /* generate product */
1560  int_to_expression(efp->icoef),
1561  efp->expr);
1562  }
1563 
1564  if(efp->ishift != 0) {
1565  /* generate addition or substraction */
1566  string operator = (efp->ishift>0) ? PLUS_OPERATOR_NAME
1568  tmp_expr= MakeBinaryCall(entity_intrinsic(operator),
1569  tmp_expr,
1570  int_to_expression(ABS(efp->ishift)));
1571  }
1572  }
1573  else {
1574  /* check */
1575  pips_assert("the expression is undefined",
1576  efp->expr == expression_undefined);
1577  /* final expression is constant efp->ishift */
1578  tmp_expr= int_to_expression(efp->ishift);
1579  }
1580 
1581  /* replace *ep by tmp_expr */
1582  *ep = tmp_expr;
1583  }
1584 }
1585 
1586 /* We are likely to end up in trouble because the regenerated
1587  expression may not be a call; for instance "n+0" is converted into
1588  a reference to n... */
1590 {
1592  regenerate_expression(efp, &e);
1593  if(expression_undefined_p(e)) {
1594  /* Nothing to do */
1595  ;
1596  }
1597  else if(expression_call_p(e)) {
1599  //list al = call_arguments(ca);
1600  call_function(ca) = call_function(nc);
1601  call_arguments(ca) = call_arguments(nc);
1602  // gen_full_free_list(al);
1603  }
1604  else if(expression_reference_p(e)) {
1605  /* We are in trouble... */
1607  /* Any memory write effect? */
1608  if(effects_all_read_p(el)) {
1610  call_arguments(ca) = NIL;
1611  }
1612  else {
1613  /* Do not change the initial call */
1614  free_expression(e);
1615  }
1616  }
1617  else {
1618  /* We are even more in trouble */
1619  pips_internal_error("Unexpected case.");
1620  }
1621 }
1622 
1624 {
1625  if(coef==0) {
1626  pips_assert("generate_monome", expr==expression_undefined);
1627  return(int_to_expression(0));
1628  }
1629  pips_assert("generate_monome", expr!=expression_undefined);
1630  if(coef==1) {
1631  return(expr);
1632  }
1633  if(coef==-1) {
1635  expr));
1636  }
1638  int_to_expression(coef),
1639  expr));
1640 }
1641 ␌
1642 /* assumes conditions checked by partial_eval_declarations()
1643  *
1644  * partial evaluation of expressions in dimensions and of
1645  * initialization expression.
1646  */
1647 
1649 {
1650  type vt = entity_type(v);
1653 
1654  /* See if the dimensions can be simplified */
1655  FOREACH(DIMENSION, d, dl) {
1658  }
1659 
1660  /* See if the initialization expression can be simplified */
1661  if(!expression_undefined_p(ie)) {
1662  /* FI: Lots of short cuts about side effects: pre and fx should be
1663  recomputed between each partial evaluation by the caller... */
1664  partial_eval_expression_and_regenerate(&ie, pre_sc, fx);
1666  /* Too bad for the memory leak of entity_initial() but I'm afraid
1667  the expression might be shared*/
1668  }
1669 }
1670 
1671 
1673 {
1674  FOREACH(ENTITY, e, el) {
1676  partial_eval_declaration(e, pre_sc, fx);
1677  }
1678 }
1679 ␌
1680 /**
1681  * apply partial eval on each statement
1682  * we cannot recurse on something other than a statement
1683  * because we use the effects & preconditions attached to the statement
1684  * @param stmt statement to partial_eval
1685  *
1686  * It is assumed that sub-expressions do not have side effects because
1687  * the same precondition is used for all of them.
1688  *
1689  * It would be simpler to transform instruction calls into instruction
1690  * expression to have fewer cases to handle. Case instruction
1691  * expression was introduced for C and made instruction call
1692  * obsolete. The same is true for value: as expressions have been
1693  * added, constant became redundant.
1694  */
1696 {
1699 
1700  pips_assert("internal current_statement was reseted",
1704 
1705  pips_debug(8, "begin with tag %d\n", instruction_tag(inst));
1706 
1710  }
1711 
1712  switch(instruction_tag(inst)) {
1713  case is_instruction_block :
1714  {
1715  /* This is no longer useful with the new representation of C
1716  declarations. */
1717  if(false) {
1719  value v = entity_initial(e);
1720  if(value_expression_p(v))
1722  stmt_prec(stmt),
1723  stmt_to_fx(stmt,fx_map));
1724  }
1725  }
1726  } break;
1727  case is_instruction_test :
1728  {
1729  test t = instruction_test(inst);
1731  stmt_prec(stmt),
1732  stmt_to_fx(stmt,fx_map));
1733  ifdebug(9) {
1735  pips_assert("stmt is consistent", statement_consistent_p(stmt));
1736  }
1737  } break;
1738  case is_instruction_loop :
1739  {
1740  loop l = instruction_loop(inst);
1741  range r = loop_range(l);
1742  effects fx = stmt_to_fx(stmt,fx_map);
1743  Psysteme sc = stmt_prec(stmt);
1744 
1745  /* Assuming no side-effects in loop bounds, sc is constant... */
1746 
1748  sc,
1749  fx);
1751  sc,
1752  fx);
1754  sc,
1755  fx);
1758 
1759  ifdebug(9) {
1761  pips_assert("stmt is consistent", statement_consistent_p(stmt));
1762  }
1763  } break;
1764  case is_instruction_forloop :
1765  {
1766  forloop fl = instruction_forloop(inst);
1767 
1769  stmt_prec(stmt),
1770  stmt_to_fx(stmt,fx_map));
1771  // FI: wrong precondition!
1773  stmt_prec(stmt),
1774  stmt_to_fx(stmt,fx_map));
1775  // FI: wrong precondition!
1777  stmt_prec(stmt),
1778  stmt_to_fx(stmt,fx_map));
1779  //add_live_loop_index(loop_index(l));
1780  //rm_live_loop_index(loop_index(l));
1781 
1782  if(get_debug_level()>=9) {
1785  }
1786  } break;
1788  {
1789  /* The whileloop precondition cannot be used to evaluate the
1790  while condition. It must be unioned with the body postcondition.
1791  partial_eval_expression_and_regenerate(&whileloop_condition(l),
1792  stmt_prec(stmt),
1793  stmt_to_fx(stmt,fx_map));
1794  */
1795  /* Also, two kinds of while must be handled */
1796  /* Short term fix... we might as well not try anything for
1797  the while condition */
1798  /* partial_eval_expression_and_regenerate(&whileloop_condition(l),
1799  SC_UNDEFINED, stmt_to_fx(stmt,fx_map));
1800  */
1801 
1802  ifdebug(9) {
1804  pips_assert("stmt is consistent", statement_consistent_p(stmt));
1805  }
1806  } break;
1807  case is_instruction_call :
1808  {
1810  stmt_prec(stmt),
1811  stmt_to_fx(stmt,fx_map));
1812  } break;
1813  case is_instruction_goto:
1814  break;
1816  break;
1819  stmt_prec(stmt),
1820  stmt_to_fx(stmt,fx_map));
1821  break;
1822  default :
1823  pips_internal_error("Bad instruction tag %d", instruction_tag(inst));
1824  }
1826  pop_statement_global_stack(); // for warnings
1827 }
1828 
1829 /* Top-level function
1830  */
1831 
1832 bool partial_eval(const char* module_name)
1833 {
1834  entity module;
1836 
1837  /* be carrefull not to get any mapping before the code */
1838  /* DBR_CODE will be changed: argument "pure" is true because
1839  partial_eval() *modifies* DBR_CODE. */
1840  /* still bugs in dbm because effects are stored on disc after this phase */
1841 
1844 
1846  (statement) db_get_memory_resource(DBR_CODE, module_name, true));
1847 
1850 
1851  init_use_proper_effects(module_name); /* uses set_proper_effects_map */
1852 
1853  /* preconditions may need to print preconditions for debugging purposes */
1855  db_get_memory_resource(DBR_CUMULATED_EFFECTS, module_name, true));
1856 
1858 
1860 
1862 
1863  debug_on("PARTIAL_EVAL_DEBUG_LEVEL");
1866  debug_off();
1867 
1868  /* Reorder the module, because new statements may have been generated. */
1870 
1872 
1881 
1882  return true;
1883 }
1884 
1885 
1886 /*------------------------------
1887 
1888  END OF FILE
1889 
1890 --------------------------------*/
1891 
1892 
1893 
1894 
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
effects apply_statement_effects(statement_effects f, statement k)
Definition: effects.c:1007
call make_call(entity a1, list a2)
Definition: ri.c:269
value make_value_expression(expression _field_)
Definition: ri.c:2850
syntax make_syntax_call(call _field_)
Definition: ri.c:2500
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
bool statement_consistent_p(statement p)
Definition: ri.c:2195
bool expression_consistent_p(expression p)
Definition: ri.c:859
void free_expression(expression p)
Definition: ri.c:853
void free_basic(basic p)
Definition: ri.c:107
static statement module_statement
Definition: alias_check.c:125
void free_arguments(cons *args)
Definition: arguments.c:218
bool entity_is_argument_p(entity e, cons *args)
Definition: arguments.c:150
cons * arguments_rm_entity(cons *a, entity e)
Definition: arguments.c:94
void dump_arguments(cons *args)
entity_name is a macro, hence the code replication
Definition: arguments.c:69
#define VALUE_TO_INT(val)
#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 ABS(x)
was: #define value_mult(v,w) value_direct_multiply(v,w) #define value_product(v,w) value_direct_produ...
#define value_eq(v1, v2)
bool operators on values
bool base_contains_variable_p(Pbase b, Variable v)
bool base_contains_variable_p(Pbase b, Variable v): returns true if variable v is one of b's elements...
Definition: base.c:136
bool integer_constant_p(entity ent, int *int_p)
Returns the double value associated to a PIPS constant.
Definition: constant.c:542
bool integer_symbolic_constant_p(entity ent, int *int_p)
(*int_p) gets integer constant if any
Definition: constant.c:556
entity int_to_entity(_int c)
Definition: constant.c:453
#define min(a, b)
#define max(a, b)
bool proper_rw_effects_undefined_p(void)
void reset_proper_rw_effects(void)
void set_proper_rw_effects(statement_effects)
void set_cumulated_rw_effects(statement_effects)
void reset_cumulated_rw_effects(void)
statement_effects get_proper_rw_effects(void)
list expression_to_proper_effects(expression)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
action_kind effect_action_kind(effect)
Definition: effects.c:1055
bool effects_all_read_p(list)
Check that all effects in el are read effects.
Definition: effects.c:1141
#define effects_undefined
Definition: effects.h:688
#define action_kind_store_p(x)
Definition: effects.h:259
#define effect_action(x)
Definition: effects.h:642
struct _newgen_struct_effects_ * effects
Definition: effects.h:138
#define action_write_p(x)
Definition: effects.h:314
#define effects_effects(x)
Definition: effects.h:710
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
struct eformat eformat_t
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
#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 REFCAR(pc)
Get the adress of the first element of a list.
Definition: newgen_list.h:119
#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
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define MAPL(_map_list_cp, _code, _l)
Apply some code on the addresses of all the elements of a list.
Definition: newgen_list.h:203
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
Definition: database.c:755
#define DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
Definition: pipsdbm-local.h:66
bool declaration_statement_p(statement)
Had to be optimized according to Beatrice Creusillet.
Definition: statement.c:224
void hash_table_print_header(hash_table htp, FILE *fout)
this function prints the header of the hash_table pointed to by htp on the opened stream fout.
Definition: hash.c:510
#define debug_on(env)
Definition: misc-local.h:157
#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_user_warning
Definition: misc-local.h:146
#define FORTRAN_DIV(n, d)
Definition: misc-local.h:213
#define FORTRAN_MOD(n, m)
Definition: misc-local.h:215
#define C_MODULO(n, m)
Definition: misc-local.h:216
#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 debug_off()
Definition: misc-local.h:160
#define user_error(fn,...)
Definition: misc-local.h:265
#define abort()
Definition: misc-local.h:53
int get_debug_level(void)
GET_DEBUG_LEVEL returns the current debugging level.
Definition: debug.c:67
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
#define HASH_MAP(k, v, code, ht)
Definition: newgen_hash.h:60
#define HASH_UNDEFINED_VALUE
value returned by hash_get() when the key is not found; could also be called HASH_KEY_NOT_FOUND,...
Definition: newgen_hash.h:56
#define hash_table_undefined
Value of an undefined hash_table.
Definition: newgen_hash.h:49
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
eformat_t partial_eval_mod_operator(expression *ep1, expression *ep2, Psysteme ps, effects fx)
bool partial_eval(const char *module_name)
Top-level function.
eformat_t partial_eval_binary_operator_old(entity func, cons *la, Psysteme ps, effects fx)
effects stmt_to_fx(statement stmt, statement_effects fx_map)
returns proper effects associated to statement stmt
Definition: partial_eval.c:179
static statement partial_eval_current_statement
Definition: partial_eval.c:127
eformat_t partial_eval_expression(expression e, Psysteme ps, effects fx)
Definition: partial_eval.c:318
#define PERFORM_MULTIPLICATION
Definition: partial_eval.c:718
#define PERFORM_MAXIMUM
Definition: partial_eval.c:725
eformat_t partial_eval_expression_and_copy(expression expr, Psysteme ps, effects fx)
Definition: partial_eval.c:305
bool eformat_equivalent_p(eformat_t ef1, eformat_t ef2)
Definition: partial_eval.c:269
eformat_t partial_eval_div_or_mod_operator(int token, expression *ep1, expression *ep2, Psysteme ps, effects fx)
Definition: partial_eval.c:993
eformat_t partial_eval_max_operator(expression *ep1, expression *ep2, Psysteme ps, effects fx)
void partial_eval_declaration(entity v, Psysteme pre_sc, effects fx)
assumes conditions checked by partial_eval_declarations()
void init_use_preconditions(const char *module_name)
Definition: partial_eval.c:216
static bool live_loop_index_p(entity i)
Definition: partial_eval.c:151
void regenerate_call(eformat_t *efp, call ca)
We are likely to end up in trouble because the regenerated expression may not be a call; for instance...
eformat_t partial_eval_syntax(expression e, Psysteme ps, effects fx)
Definition: partial_eval.c:355
eformat_t partial_eval_unary_operator(entity func, cons *la, Psysteme ps, effects fx)
Definition: partial_eval.c:680
#define PERFORM_ADDITION
Definition: partial_eval.c:716
eformat_t partial_eval_plus_operator(expression *ep1, expression *ep2, Psysteme ps, effects fx)
Definition: partial_eval.c:924
eformat_t partial_eval_update_operators(expression *ep1 __attribute__((__unused__)), expression *ep2, Psysteme ps, effects fx)
FI: a better job could be done by distinguishing between the different kinds of operators.
void partial_eval_statement(statement stmt)
apply partial eval on each statement we cannot recurse on something other than a statement because we...
eformat_t partial_eval_c_mod_operator(expression *ep1, expression *ep2, Psysteme ps, effects fx)
void partial_eval_call_and_regenerate(call ca, Psysteme ps, effects fx)
Definition: partial_eval.c:553
#define PERFORM_DIVISION
Definition: partial_eval.c:719
eformat_t partial_eval_mult_operator(expression *ep1, expression *ep2, Psysteme ps, effects fx)
Definition: partial_eval.c:727
#define PERFORM_SUBTRACTION
Definition: partial_eval.c:717
static void rm_live_loop_index(entity i)
Definition: partial_eval.c:164
#define PERFORM_C_MODULO
Definition: partial_eval.c:723
#define PERFORM_MODULO
Definition: partial_eval.c:722
void partial_eval_declarations(list el, Psysteme pre_sc, effects fx)
static list live_loop_indices
when formating is useless (ie.
Definition: partial_eval.c:126
bool entity_written_p(entity ent, effects fx)
Definition: partial_eval.c:198
eformat_t partial_eval_binary_operator(entity func, cons *la, Psysteme ps, effects fx)
void init_use_proper_effects(const char *module_name)
Definition: partial_eval.c:171
eformat_t partial_eval_min_or_max_operator(int token, expression *ep1, expression *ep2, Psysteme ps, effects fx)
expression generate_monome(int coef, expression expr)
void reset_live_loop_indices()
Definition: partial_eval.c:135
eformat_t partial_eval_div_operator(expression *ep1, expression *ep2, Psysteme ps, effects fx)
eformat_t partial_eval_minus_c_operator(expression *ep1, expression *ep2, Psysteme ps, effects fx)
Definition: partial_eval.c:972
eformat_t partial_eval_call(call ec, Psysteme ps, effects fx)
Definition: partial_eval.c:574
eformat_t partial_eval_plus_or_minus_operator(int token, expression *ep1, expression *ep2, Psysteme ps, effects fx)
Definition: partial_eval.c:792
void dump_live_loop_indices()
Definition: partial_eval.c:145
eformat_t partial_eval_call_expression(expression exp, Psysteme ps, effects fx)
Definition: partial_eval.c:664
static struct perform_switch binary_operator_switch[]
static void add_live_loop_index(entity i)
Definition: partial_eval.c:157
#define PERFORM_MINIMUM
Definition: partial_eval.c:724
void set_live_loop_indices()
cproto-generated files
Definition: partial_eval.c:129
Psysteme stmt_prec(statement stmt)
Definition: partial_eval.c:230
void transformer_map_print(void)
Definition: partial_eval.c:252
eformat_t partial_eval_plus_c_operator(expression *ep1, expression *ep2, Psysteme ps, effects fx)
Definition: partial_eval.c:937
eformat_t partial_eval_reference(expression e, Psysteme ps, effects fx)
Definition: partial_eval.c:436
void regenerate_expression(eformat_t *efp, expression *ep)
in order to regenerate expression from eformat.
eformat_t partial_eval_minus_operator(expression *ep1, expression *ep2, Psysteme ps, effects fx)
Definition: partial_eval.c:959
void partial_eval_expression_and_regenerate(expression *ep, Psysteme ps, effects fx)
Definition: partial_eval.c:284
void print_eformat(eformat_t ef, char *name)
Definition: partial_eval.c:277
static eformat_t eformat_undefined
Hypotheses pour l'implementation:
Definition: partial_eval.c:102
eformat_t partial_eval_power_operator(expression *ep1, expression *ep2, Psysteme ps, effects fx)
eformat_t partial_eval_min_operator(expression *ep1, expression *ep2, Psysteme ps, effects fx)
void unnormalize_expression(void *st)
void unnormalize_expression(expression exp): puts all the normalized field of expressions in "st" to ...
Definition: normalize.c:452
static char * module
Definition: pips.c:74
void print_expression(expression e)
no file descriptor is passed to make is easier to use in a debugging stage.
Definition: expression.c:58
#define print_transformer(t)
Definition: print.c:357
#define print_effects(e)
Definition: print.c:334
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
#define MAX_OPERATOR_NAME
#define POWER_OPERATOR_NAME
#define BITWISE_OR_UPDATE_OPERATOR_NAME
#define C_MODULO_OPERATOR_NAME
#define MINUS_OPERATOR_NAME
#define ENTITY_UNARY_MINUS_P(e)
#define DIVIDE_UPDATE_OPERATOR_NAME
#define PLUS_OPERATOR_NAME
#define NORMALIZE_EXPRESSION(e)
#define MAX0_OPERATOR_NAME
#define MIN0_OPERATOR_NAME
#define LEFT_SHIFT_UPDATE_OPERATOR_NAME
#define MULTIPLY_UPDATE_OPERATOR_NAME
#define MINUS_UPDATE_OPERATOR_NAME
#define is_instruction_block
soft block->sequence transition
#define CONTINUE_FUNCTION_NAME
#define entity_variable_p(e)
An entity_variable_p(e) may hide a typedef and hence a functional type.
#define DIVIDE_OPERATOR_NAME
#define UNARY_MINUS_OPERATOR_NAME
#define RIGHT_SHIFT_UPDATE_OPERATOR_NAME
#define PLUS_UPDATE_OPERATOR_NAME
#define ENTITY_ADDRESS_OF_P(e)
#define MINUS_C_OPERATOR_NAME
#define MULTIPLY_OPERATOR_NAME
#define ASSIGN_OPERATOR_NAME
Definition: ri-util-local.h:95
#define MODULO_OPERATOR_NAME
#define PLUS_C_OPERATOR_NAME
#define MIN_OPERATOR_NAME
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
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
entity operator_neutral_element(entity op)
Definition: entity.c:2593
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
int ipow(int vg, int vd)
FI: such a function should exist in Linear/arithmetique.
Definition: eval.c:769
expression make_vecteur_expression(Pvecteur pv)
make expression for vector (Pvecteur)
Definition: expression.c:1650
bool expression_call_p(expression e)
Definition: expression.c:415
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
bool expression_equal_p(expression e1, expression e2)
Syntactic equality e1==e2.
Definition: expression.c:1347
void update_expression_syntax(expression e, syntax s)
frees expression syntax of e and replace it by the new syntax s
Definition: expression.c:3564
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188
expression make_op_exp(char *op_name, expression exp1, expression exp2)
================================================================
Definition: expression.c:2012
expression MakeUnaryCall(entity f, expression a)
Creates a call expression to a function with one argument.
Definition: expression.c:342
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
entity expression_to_entity(expression e)
just returns the entity of an expression, or entity_undefined
Definition: expression.c:3140
bool reference_scalar_p(reference r)
This function returns true if Reference r is scalar.
Definition: expression.c:3530
bool c_language_module_p(entity m)
Definition: module.c:447
bool fortran_language_module_p(entity m)
Definition: module.c:452
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
statement pop_statement_global_stack(void)
Definition: static.c:352
bool variable_entity_p(entity)
variable.c
Definition: variable.c:70
int type_memory_size(type)
Definition: size.c:248
expression variable_initial_expression(entity)
Returns a copy of the initial (i.e.
Definition: variable.c:1899
void push_statement_on_statement_global_stack(statement)
Definition: static.c:333
void free_statement_global_stack(void)
Definition: static.c:358
void make_statement_global_stack(void)
Definition: static.c:318
#define value_tag(x)
Definition: ri.h:3064
#define syntax_reference_p(x)
Definition: ri.h:2728
#define transformer_undefined
Definition: ri.h:2847
#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 normalized_linear_p(x)
Definition: ri.h:1779
#define forloop_initialization(x)
Definition: ri.h:1366
#define call_function(x)
Definition: ri.h:709
#define EXPRESSION_(x)
Definition: ri.h:1220
#define reference_variable(x)
Definition: ri.h:2326
#define sizeofexpression_type(x)
Definition: ri.h:2406
#define range_upper(x)
Definition: ri.h:2290
#define forloop_increment(x)
Definition: ri.h:1370
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define syntax_call_p(x)
Definition: ri.h:2734
#define instruction_loop(x)
Definition: ri.h:1520
#define statement_ordering(x)
Definition: ri.h:2454
#define sizeofexpression_expression(x)
Definition: ri.h:2409
#define syntax_cast(x)
Definition: ri.h:2739
#define syntax_application(x)
Definition: ri.h:2748
#define dimension_lower(x)
Definition: ri.h:980
#define type_variable(x)
Definition: ri.h:2949
#define basic_pointer_p(x)
Definition: ri.h:635
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
@ is_value_intrinsic
Definition: ri.h:3034
@ is_value_unknown
Definition: ri.h:3035
@ is_value_constant
Definition: ri.h:3033
@ is_value_code
Definition: ri.h:3031
@ is_value_symbolic
Definition: ri.h:3032
@ is_syntax_range
Definition: ri.h:2692
@ is_syntax_application
Definition: ri.h:2697
@ is_syntax_cast
Definition: ri.h:2694
@ is_syntax_call
Definition: ri.h:2693
@ is_syntax_va_arg
Definition: ri.h:2698
@ is_syntax_reference
Definition: ri.h:2691
@ is_syntax_sizeofexpression
Definition: ri.h:2695
@ is_syntax_subscript
Definition: ri.h:2696
#define range_increment(x)
Definition: ri.h:2292
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define cast_expression(x)
Definition: ri.h:747
#define subscript_indices(x)
Definition: ri.h:2563
#define entity_undefined_p(x)
Definition: ri.h:2762
#define expression_undefined
Definition: ri.h:1223
@ is_instruction_goto
Definition: ri.h:1473
@ is_instruction_unstructured
Definition: ri.h:1475
@ is_instruction_whileloop
Definition: ri.h:1472
@ is_instruction_expression
Definition: ri.h:1478
@ is_instruction_test
Definition: ri.h:1470
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_forloop
Definition: ri.h:1477
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define entity_name(x)
Definition: ri.h:2790
#define transformer_relation(x)
Definition: ri.h:2873
#define expression_normalized(x)
Definition: ri.h:1249
#define dimension_upper(x)
Definition: ri.h:982
#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 instruction_forloop(x)
Definition: ri.h:1538
#define syntax_call(x)
Definition: ri.h:2736
#define instruction_expression(x)
Definition: ri.h:1541
#define expression_undefined_p(x)
Definition: ri.h:1224
#define test_condition(x)
Definition: ri.h:2833
#define subscript_array(x)
Definition: ri.h:2561
#define application_function(x)
Definition: ri.h:508
#define range_lower(x)
Definition: ri.h:2288
#define variable_dimensions(x)
Definition: ri.h:3122
#define statement_declarations(x)
Definition: ri.h:2460
#define statement_instruction(x)
Definition: ri.h:2458
#define instruction_call(x)
Definition: ri.h:1529
#define syntax_subscript(x)
Definition: ri.h:2745
#define loop_range(x)
Definition: ri.h:1642
#define forloop_condition(x)
Definition: ri.h:1368
#define call_arguments(x)
Definition: ri.h:711
#define instruction_test(x)
Definition: ri.h:1517
#define statement_undefined_p(x)
Definition: ri.h:2420
#define entity_type(x)
Definition: ri.h:2792
#define call_undefined
Definition: ri.h:685
#define statement_number(x)
Definition: ri.h:2452
#define value_expression_p(x)
Definition: ri.h:3080
#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 value_expression(x)
Definition: ri.h:3082
#define loop_index(x)
Definition: ri.h:1640
#define variable_basic(x)
Definition: ri.h:3120
#define statement_undefined
Definition: ri.h:2419
#define entity_initial(x)
Definition: ri.h:2796
struct Ssysteme * Psysteme
Pbase sc_to_minimal_basis(Psysteme ps)
creation d'une base contenant toutes les variables apparaissant avec des coefficients non-nuls dans l...
Definition: sc_alloc.c:76
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
bool sc_minmax_of_variable2(volatile Psysteme ps, Variable var, Value *pmin, Value *pmax)
void sc_minmax_of_variable2(Psysteme ps, Variable var, Value *pmin, *pmax): examine un systeme pour t...
Definition: sc_eval.c:330
Value b2
Definition: sc_gram.c:105
Value b1
booleen indiquant quel membre est en cours d'analyse
Definition: sc_gram.c:105
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
int printf()
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
void module_to_value_mappings(entity m)
void module_to_value_mappings(entity m): build hash tables between variables and values (old,...
Definition: mappings.c:624
transformer load_statement_precondition(statement)
void reset_precondition_map(void)
void set_precondition_map(statement_mapping)
statement_mapping get_precondition_map(void)
#define ifdebug(n)
Definition: sg.c:47
static bool ok
#define intptr_t
Definition: stdint.in.h:294
#define MAX(x, y)
Definition: string.c:110
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
expression expr
eformat_t(* binary_operator)(expression *, expression *, Psysteme, effects)
string operator_name
Definition: statement.c:54
transformer transformer_range(transformer tf)
Return the range of relation tf in a newly allocated transformer.
Definition: transformer.c:714
void free_value_mappings(void)
Normal call to free the mappings.
Definition: value.c:1212
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207
#define base_rm(b)
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_UNDEFINED