PIPS
basic.c
Go to the documentation of this file.
1 /*
2 
3  $Id: basic.c 23412 2017-08-09 15:07:09Z irigoin $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27  /* transformer package - basic routines
28  *
29  * Francois Irigoin
30  */
31 
32 #include <stdio.h>
33 #include <stdlib.h>
34 
35 #include "vecteur.h"
36 #include "contrainte.h"
37 #include "sc.h"
38 
39 #include "genC.h"
40 #include "linear.h"
41 #include "ri.h"
42 
43 #include "misc.h"
44 #include "ri-util.h"
45 #include "effects-util.h"
46 
47 #include "transformer.h"
48 
50 {
51  /* FI: I do not reduce transformer_dup() to a macro calling
52  copy_transformer() because I do not want to create problems with
53  the link edit and because I want to keep the assertion */
54 
55  Psysteme sc = SC_UNDEFINED;
56  transformer t_out;
57 
58  pips_assert("transformer t_in is not undefined", t_in != transformer_undefined);
59 
61  pips_assert("transformer_dup", !SC_UNDEFINED_P(sc));
62  t_out = copy_transformer(t_in);
63 
64  return t_out;
65 }
66 
67 
69 {
71 }
72 
74  va_list args;
75 
76  /* Analyze in args the variadic arguments that may be after t: */
77  va_start(args, t);
78  /* Since a variadic function in C must have at least 1 non variadic
79  argument (here the s), just skew the varargs analysis: */
80  do {
82  /* Get the next argument: */
83  t = va_arg(args, transformer);
84  } while(t!=NULL);
85  /* Release the variadic analyzis: */
86  va_end(args);
87 }
88 
90 {
91  /* I should use gen_free directly but Psysteme is not yet properly
92  interfaced with NewGen */
93  Psysteme s;
94 
95  pips_assert("transformer_free", t != transformer_undefined);
96 
98  sc_rm(s);
99  predicate_system_(transformer_relation(t)) = SC_UNDEFINED;
100  /* gen_free should stop before trying to free a Psysteme and
101  won't free entities in arguments because they are tabulated */
102  /* commented out for DRET demo */
103  /*
104  gen_free(t);
105  */
106  /* end of DRET demo */
107 }
108 
109 /* Allocate an identity transformer */
111 {
112  /* return make_transformer(NIL, make_predicate(SC_RN)); */
113  /* en fait, on voudrait initialiser a "liste de contraintes vide" */
114  return make_transformer(NIL,
117 }
118 
119 /* Allocate an empty transformer */
121 {
122  return make_transformer(NIL,
124 }
125 
126 /* Do not allocate an empty transformer, but transform an allocated
127  * transformer into an empty_transformer.
128  *
129  * Pretty dangerous because the predicate contained in t may have been
130  * deleted before empty_transformer is called. It is not clear that
131  * the predicate of t can be freed or not: it is up to the caller to
132  * be aware of the problem.
133  *
134  * This function is risky to use. It can cause either a memory leak if
135  * the predicate is not freed, or a double free if the pointer in the
136  * transformer is already dangling. If the predicate has already been
137  * freed during some processing at the linear level, the caller must
138  * update the pointer transformer_relation(t) with:
139  *
140  * transformer_relation(t) = relation_undefined;
141  *
142  * before the call.
143  */
145 {
150  return t;
151 }
152 
153 /* Check that t is an identity function */
155 {
156  /* no variables are modified; no constraints exist on their values */
157 
158  Psysteme s;
159 
160  pips_assert("transformer_identity_p", t != transformer_undefined);
162  return transformer_arguments(t) == NIL && sc_nbre_egalites(s) == 0
163  && sc_nbre_inegalites(s) == 0;
164 }
165 
166 /* Check that transformer t is the canonical representation of an
167  * empty transformer.
168  *
169  * See transformer_empty_p(), transformer_strongly_empty_p() if you
170  * need to check that a set of affine constraints is not feasible.
171  */
173 {
174  Psysteme s;
175 
176  pips_assert("transformer_identity_p", t != transformer_undefined);
178  return sc_empty_p(s) && ENDP(transformer_arguments(t));
179 }
180 
181 /* Check that transformer t is the canonical representation of the
182  whole afine space defined by its basis */
184 {
185  Psysteme s;
186 
187  pips_assert("transformer_identity_p", t != transformer_undefined);
189  return sc_nbre_egalites(s)==0 && sc_nbre_inegalites(s)==0;
190 }
191 ␌
192 /* CHANGE THIS NAME: no loop index please, it's not directly linked
193  * to loops!!!
194  */
195 
196 /* Add in tf the information that v is striclty positive, strictly negative or zero.
197  *
198  * Assume that v is a value and tf is defined.
199  */
201  entity v,
202  int v_sign)
203 {
205 
206  ifdebug(1) {
207  pips_assert("Transformer tf is consistent on entrance",
209  }
210 
212 
213  psyst->base = base_add_variable(psyst->base, (Variable) v);
214  psyst->dimension = base_dimension(psyst->base);
215 
216  if(v_sign!=0) {
217  Pvecteur cv;
218  Pcontrainte ineq;
219  if(v_sign>0) {
220  cv = vect_new((Variable) v, VALUE_MONE);
222  }
223  else {
224  /* v_sign<0 */
225  cv = vect_new((Variable) v, VALUE_ONE);
227  }
228  ineq = contrainte_make(cv);
229  sc_add_inegalite(psyst, ineq);
230  }
231  else {
232  /* v_sign==0*/
233  Pvecteur cv = vect_new((Variable) v, VALUE_ONE);
235 
236  sc_add_egalite(psyst, eq);
237  }
238 
239  ifdebug(1) {
240  pips_assert("Transformer tf is consistent on exit",
242  }
243 
244  return tf;
245 }
246 
247 /* transformer transformer_add_loop_index(transformer t, entity i,
248  * Pvecteur incr):
249  * add the index incrementation expression incr for loop index i to
250  * transformer t.
251  *
252  * t = intersection(t, i#new = i#old + incr)
253  *
254  * incr is supposed to be compatible with the value mappings
255  *
256  * Pvecteur incr should not be used after a call to transformer_add_index
257  * because it is shared by t and modified
258  */
261 transformer t;
262 entity i;
263 Pvecteur incr;
264 {
265  /* Psysteme * ps =
266  &((Psysteme) predicate_system(transformer_relation(t))); */
268  entity i_old = entity_to_old_value(i);
269  entity i_new = entity_to_new_value(i);
270  entity i_rep = value_to_variable(i_new);
271 
273  psyst->base = vect_add_variable(psyst->base, (Variable) i_new);
274  psyst->base = vect_add_variable(psyst->base, (Variable) i_old);
275  psyst->dimension = vect_size(psyst->base);
276  vect_chg_coeff(&incr, (Variable) i_new, -1);
277  vect_chg_coeff(&incr, (Variable) i_old, 1);
278  psyst = sc_equation_add(psyst, contrainte_make(incr));
279 
280  return t;
281 }
282 
283 /* Add an update of variable v into t
284  *
285  * NL : this function is not finish
286  * do the same thing than transformer_add_value_update for the moment
287  * TODO
288  */
290 {
292  entity v_new = entity_to_new_value(v);
293  entity v_old = entity_to_old_value(v);
294  entity v_rep = value_to_variable(v_new);
295 
297  if(!base_contains_variable_p(psyst->base, (Variable) v_new)) {
298  psyst->base = base_add_variable(psyst->base, (Variable) v_new);
299  }
300  if(!base_contains_variable_p(psyst->base, (Variable) v_old)) {
301  psyst->base = base_add_variable(psyst->base, (Variable) v_old);
302  }
303  psyst->dimension = vect_size(psyst->base);
304 
305 //
306 // pips_assert("before value substitution\n", transformer_consistency_p(t));
307 //// t = transformer_value_substitute(t, v_new, v_old);
308 //
309 // pips_debug(9, "before tes\nt");
310 // if(base_contains_variable_p(psyst->base, (Variable) v_new)) {
311 // if(!base_contains_variable_p(psyst->base, (Variable) v_old)) {
312 // pips_debug(9, "rename variable\n");
313 // (void) sc_variable_rename(psyst,(Variable) v_new, (Variable)v_old);
314 // }
315 // }
316 // pips_assert("after value substitution\n", transformer_consistency_p(t));
317  return t;
318 }
319 
320 /* Add an update of variable v to t (a value cannot be updated) */
322 {
323  entity nv = entity_to_new_value(v);
324  entity ov = entity_to_old_value(v);
325 
326  if(!transformer_empty_p(t)) {
328 
330  if(!base_contains_variable_p(psyst->base, (Variable) nv))
331  psyst->base = base_add_variable(psyst->base, (Variable) nv);
332  if(!base_contains_variable_p(psyst->base, (Variable) ov))
333  psyst->base = base_add_variable(psyst->base, (Variable) ov);
334  psyst->dimension = vect_size(psyst->base);
335  }
336 
337  return t;
338 }
339 
341 {
342  FOREACH(ENTITY, v, vl) {
344  }
345  return t;
346 }
347 
349 transformer tf;
350 Pvecteur i;
351 bool equality;
352 {
353  Pcontrainte c;
354  Psysteme sc;
355 
356  pips_assert("tf is defined", tf != transformer_undefined
357  && tf != (transformer) NULL);
358 
359  if(VECTEUR_NUL_P(i)) {
360  user_warning("transformer_constraint_add",
361  "trivial constraint 0 %s 0 found: code should be optimized\n",
362  (equality)? "==" : "<=");
363  return tf;
364  }
365 
366  c = contrainte_make(i);
368 
369  sc = sc_constraint_add(sc, c, equality);
370 
371  return tf;
372 }
373 
376 transformer tf;
377 Pvecteur i;
378 {
379  return transformer_constraint_add(tf, i, false);
380 }
381 
384 transformer tf;
385 Pvecteur i;
386 {
387  return transformer_constraint_add(tf, i, true);
388 }
389 
392 transformer tf;
393 Pcontrainte eqs;
394 {
395  /* please, do not introduce any sharing at the Pcontrainte level
396  you do not know how they have to be chained in diferent transformers;
397  do not introduce any sharing at the Pvecteur level; I'm not
398  sure it's so useful, but think of what would happen if one transformer
399  is renamed... */
400  for(;eqs!=CONTRAINTE_UNDEFINED; eqs = eqs->succ)
401  (void) transformer_constraint_add(tf,
403  true);
404  return tf;
405 }
406 
407 /* Warning: */
410 {
412 
413  for(ineq = ineqs; !CONTRAINTE_UNDEFINED_P(ineq); ineq = contrainte_succ(ineq))
414  (void) transformer_constraint_add(tf,
415  contrainte_vecteur(ineq),
416  false);
417  return tf;
418 }
419 
422 {
423  entity v_new = entity_to_new_value(v);
424  entity v_old = entity_to_old_value(v);
425  Pvecteur eq = vect_new((Variable) v_new, (Value) 1);
426 
427  vect_add_elem(&eq, (Variable) v_old, (Value) -1);
428  tf = transformer_equality_add(tf, eq);
431 
432  return tf;
433 }
434 
435 /* Add an equality between two values (two variables?) */
437 {
438  Pvecteur eq = vect_new((Variable) v1, (Value) 1);
439 
440  //pips_assert("v1 has values", entity_has_values_p(v1));
441  //pips_assert("v2 has values", entity_has_values_p(v2));
442 
444  tf = transformer_equality_add(tf, eq);
445 
446  return tf;
447 }
448 
449 /* Add an equality between a value and an integer constant: v==cst */
451 {
453 
454  //pips_assert("v1 has values", entity_has_values_p(v1));
455  //pips_assert("v2 has values", entity_has_values_p(v2));
456 
457  vect_add_elem(&eq, TCST, (Value) cst);
458  tf = transformer_equality_add(tf, eq);
459 
460  return tf;
461 }
462 
463 /* Add the equality v1 <= v2 or v1 < v2 */
465 {
467 
469  if(strict_p)
471  tf = transformer_inequality_add(tf, eq);
472 
473  return tf;
474 }
475 
476 /* Add the inequality v <= cst or v >= cst */
478 {
480 
481  if(less_than_p) {
482  eq = vect_new((Variable) v, VALUE_ONE);
483  vect_add_elem(&eq, TCST, (Value) -cst);
484  }
485  else {
486  eq = vect_new((Variable) v, VALUE_MONE);
487  vect_add_elem(&eq, TCST, (Value) cst);
488  }
489 
490  tf = transformer_inequality_add(tf, eq);
491 
492  return tf;
493 }
494 
495 /* Add the inequality v <= a x + cst or v >= a x + cst */
497 {
499 
500  if(less_than_p) {
501  eq = vect_new((Variable) v, VALUE_ONE);
502  vect_add_elem(&eq, (Variable) x, (Value) -a);
503  vect_add_elem(&eq, TCST, (Value) -cst);
504  }
505  else {
506  eq = vect_new((Variable) v, VALUE_MONE);
507  vect_add_elem(&eq, TCST, (Value) cst);
508  vect_add_elem(&eq, (Variable) x, (Value) a);
509  }
510 
511  tf = transformer_inequality_add(tf, eq);
512 
513  return tf;
514 }
515 
516 /* Add the equality v = a x + cst */
518 {
520 
521  vect_add_elem(&eq, (Variable) x, (Value) -a);
522  vect_add_elem(&eq, TCST, (Value) -cst);
523 
524  tf = transformer_equality_add(tf, eq);
525 
526  return tf;
527 }
528 
529 /* Add the inequality v <= a x or v >= a x */
531 {
532  return transformer_add_inequality_with_affine_term(tf, v, x, a, VALUE_ZERO, less_than_p);
533 }
534 
535 /* Add the constraint a1 v1 + a2 v2 + a3 v3 + cst <= or == 0 */
536 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)
537 {
538  Pvecteur eq = vect_new((Variable) v1, (Value) a1);
539  vect_add_elem(&eq, (Variable) v2, (Value) a2);
540  vect_add_elem(&eq, (Variable) v3, (Value) a3);
541  vect_add_elem(&eq, TCST, (Value) cst);
542 
543  if(equation_p)
544  tf = transformer_equality_add(tf, eq);
545  else
546  tf = transformer_inequality_add(tf, eq);
547 
548  return tf;
549 }
550 ␌
552 {
554 }
555 
557 {
559 }
560 
562 {
563  list args = transformer_arguments(t);
564  bool consistent = true;
566  Pbase b = sc_base(sc);
567 
568  /* If no final state can be reached, no variable can be changed in between */
569  if(sc_empty_p(sc)) {
570  consistent = ENDP(args);
571  pips_assert("Empty transformer must have no arguments", consistent);
572  }
573  else if(!is_weak) {
574  /* If a variable appears as argument, its new value must be in the basis
575  * See for instance, effects_to_transformer()
576  */
577 
578  MAP(ENTITY, e, {
580  /*
581  pips_assert("Argument is in the basis", base_contains_variable_p(b, (Variable) v));
582  */
583  if(!base_contains_variable_p(b, (Variable) v)) {
584  /* pips_user_warning("No value for argument %s in relation basis\n",
585  entity_name(e)); */
586  pips_internal_error("No value for argument %s in relation basis",
587  entity_name(e));
588  consistent = false;
589  }
590  }, args);
591  pips_assert("Argument variables must have values in basis", consistent);
592  }
593 
594  return consistent;
595 }
596 
597 /* FI: I do not know if this procedure should always return or fail when
598  * an inconsistency is found. For instance, summary transformers for callees
599  * are inconsistent with respect to the current module. FC/CA: help...
600  *
601  * I do not understand why errors are reported only if the debug level is greater
602  * than 1. A demo effect? No, this routine is coded that way to save time on
603  * regular runs.
604  *
605  * Also, since no precise information about the inconsistency is
606  * displayed, a core dump would be welcome to retrieve pieces of
607  * information with gdb. The returned value should always be tested and a
608  * call to pips_internal_error() should always be performed if an
609  * inconsistency is detected.
610  *
611  * But, see final comment... In spite of it, I do not always return any longer. */
613 {
614  return transformer_general_consistency_p(t, false);
615 }
617 {
618  bool consistent_p = true;
619  FOREACH(TRANSFORMER, t, tl) {
620  consistent_p = consistent_p && transformer_general_consistency_p(t, false);
621  }
622  return consistent_p;
623 }
624 
625 /* Interprocedural transformers do not meet all conditions. */
627 transformer t;
628 {
629  return transformer_general_consistency_p(t, true);
630 }
631 
633 {
634 #define TRANSFORMER_CONSISTENCY_P_DEBUG_LEVEL 0
635  /* the relation should be consistent
636  * and any variable corresponding to an old value
637  * should appear in the argument list since
638  * an old value cannot (should not) be
639  * introduced unless the variable is changed and
640  * since every changed variable is
641  * in the argument list.
642  *
643  * Apparently, a variable may appear as an argument but its old value
644  * does not have to appear in the basis if it is not required by
645  * the constraints. This does not seem very safe to me (FI, 13 Nov. 95)
646  */
648  list args = transformer_arguments(tf);
649  bool consistent = true;
650 
651  /* The NewGen data structure must be fully defined */
653  consistent = transformer_defined_p(tf);
654  else
655  consistent = true;
656  if(!consistent)
658  "transformer tf is not gen_defined\n");
659 
660  /* The predicate must be weakly consistent. Every variable
661  * in the constraints must be in the basis (but not the other
662  * way round).
663  */
664  consistent = consistent && sc_weak_consistent_p(sc);
665  if(!consistent)
667  "sc is not weakly consistent\n");
668 
669  /* If an old value appears in the predicate, the corresponding
670  * variable should be an argument of the transformer
671  */
672  if(consistent) {
673  Pbase b = sc_base(sc);
674  Pbase t = BASE_UNDEFINED;
675 
676  for( t = b; !BASE_UNDEFINED_P(t) && consistent; t = t->succ) {
677  entity val = (entity) vecteur_var(t);
678 
679  /* test aliasing between arguments and relations
680  high cost testing */
681  ifdebug(8) {
682  bool aliasing = false;
683  const char* emn = entity_module_name(val);
684  const char* eln = entity_local_name(val);
685  list lt = args;
686  entity e;
687  for (lt = args; lt && !aliasing ;POP(lt)) {
688  e = ENTITY(CAR(lt));
689  consistent = consistent &&
690  (same_string_p(entity_local_name(e), eln) ?
692  : true);
693  aliasing = aliasing && entities_may_conflict_p(e,val);
694  }
695 
696  if(!consistent)
697  pips_user_warning("different global variable names in "
698  "arguments and basis: \"%s\"\n", eln);
699  if (aliasing)
700  pips_internal_error("aliasing between arguments and basis: \"%s\" ",
701  entity_name(val));
702  }
703 
704  /* FI: the next test is not safe because val can be
705  * a global value not recognized in the current
706  * context. old_value_entity_p() returns true or FALSE
707  * or pips_error.
708  *
709  * A general version of this routine is needed... The
710  * return value of a function is not recognized as a
711  * global value by old_value_entity_p
712  *
713  * old_value_entity_p() is likely to core dump on
714  * interprocedural transformers and preconditions.
715  */
717  && old_value_entity_p(val)) {
718  entity var = value_to_variable(val);
719 
720  consistent = entity_is_argument_p(var, args);
721  if(!consistent) {
722  dump_transformer(tf);
724  "Old value of \"%s\" in sc but not in arguments of transformer tf, %p\n",
725  entity_name(var), tf);
726  }
727  }
728  /* The constant term should not appear in the basis */
729  if(consistent) {
730  consistent = consistent && !term_cst(t);
731  if(!consistent)
733  "TCST in sc basis\n");
734  }
735  }
736  }
737 
738  /* The constant term should not be an argument */
739  if(consistent) {
740  MAP(ENTITY, e, {
741  consistent = consistent && (e != (entity) TCST);
742  }, args);
743  if(!consistent)
745  "transformer_consistency_p", "TCST appears in arguments\n");
746  }
747 
748  /* Check that the transformer is compatible with the current value mappings.
749  *
750  * This is not always true as you may need to import the summary transformer
751  * of a callee. Before translation, this check will most likely fail.
752  *
753  * Debugging step which does not return if an incompatibility is found.
754  */
755 
756  /* Check that every argument has a value.
757  * This is not redundant with the printout procedure which uses
758  * entity_minimal_name() and not the value mappings.
759  */
760  FOREACH(ENTITY, e, args) {
761  /*
762  pips_assert("Argument entity appears in the value mappings",
763  entity_has_values_p(e));
764  */
765  if(!entity_has_values_p(e)) {
766  /* Values returned by callees may appear in interprocedural
767  transformers */
769  && !entity_stub_sink_p(e)
770  && !entity_in_formal_area_p(e)) {
771  pips_user_warning("No value for argument %s in value mappings\n",
772  entity_name(e));
773  if(!is_weak)
774  consistent = false;
775  }
776  }
777  }
778 
779  if(consistent && !is_weak)
780  consistent = transformer_argument_consistency_p(tf);
781 
782  /* FI: let the user react and print info before core dumping */
783  /* pips_assert("transformer_consistency_p", consistent); */
784 
785  return consistent;
786 }
787 
788 /* Same as above but equivalenced variables should not appear in the
789  argument list or in the predicate basis. */
791 {
793  Pbase b = sc_base(sc);
794  Pbase e = BASE_UNDEFINED;
795  list args = transformer_arguments(t);
796  bool consistent = transformer_consistency_p(t);
797 
798  FOREACH(ENTITY, e, args) {
800 
801  if(v!=e) {
802  pips_user_warning("New value %s should be the same entity as variable %s"
803  " as long as equivalence equations are not added\n",
805  pips_assert("Argument must be a value", false);
806  }
807  }
808 
809  for(e=b; !BASE_NULLE_P(e); e = vecteur_succ(e)) {
810  entity val = (entity) vecteur_var(e);
811 
812  if(!(new_value_entity_p(val) || old_value_entity_p(val)
813  || intermediate_value_entity_p(val))) {
814  // Don't we need something else for sizeof variables ?
815  if(!entity_constant_p(val) && !entity_symbolic_p(val)
816  && !entity_null_locations_p(val)) {
817  pips_user_warning("Variable %s in basis should be an internal value",
818  entity_local_name(val));
819  pips_assert("Basis variables must be an internal value", false);
820  }
821  }
822  }
823 
824  return consistent;
825 }
826 ␌
828 {
829  list proj = NIL;
831  Pbase b = BASE_UNDEFINED;
832 
833  for(b=sc_base(sc); !BASE_NULLE_P(b); b = vecteur_succ(b)) {
834  entity v = (entity) vecteur_var(b);
835 
836  proj = CONS(ENTITY, v, proj);
837  }
838 
839  return proj;
840 }
841 
843 {
845  Pbase b = BASE_UNDEFINED;
846  bool found_p = false;
847 
848  for(b=sc_base(sc); !BASE_NULLE_P(b); b = vecteur_succ(b)) {
849  entity bv = (entity) vecteur_var(b);
850 
851  if(bv==v) {
852  found_p = true;
853  break;
854  }
855  }
856  return found_p;
857 }
858 
860 {
863  return;
864 }
865 
866 /* Get rid of all old values and arguments. Argument pre is unchanged
867  and result as is allocated. Should be a call to
868  transformer_range(). Should not be in basic.c.
869  */
872 {
873  transformer as = transformer_dup(pre);
874 
875  /* Project all old values */
877 
878  /* Redefine the arguments */
881 
882  return as;
883 }
884 
885 /* FI: this function does not end up with a consistent transformer
886  because the old value is not added to the basis of sc. Also, the
887  variable should be transformed into a new value... See next
888  function. */
890  transformer tf,
891  entity var)
892 {
893  /* Should we check that var has values? */
895  Pbase b = sc_base(sc);
896 
898  sc_base(sc) = vect_add_variable(b, (Variable) var);
899  sc_dimension(sc) = base_dimension(sc_base(sc));
900 
901  return tf;
902 }
903 
904 /* FI: like the previous function, but supposed to end up with a
905  consistent transformer. When the transformer is empty/unfeasible,
906  the variable is not added to conform to rules about standard empty
907  transformer: how could a variable be updated by a non-existing
908  transition?*/
910  entity var)
911 {
912  if(!transformer_empty_p(tf)) {
914  Pbase b = sc_base(sc);
915 
916  if(entity_has_values_p(var)) {
917  entity v_new = entity_to_new_value(var);
918  entity v_old = entity_to_old_value(var);
919 
920  /* FI: it is not well specifived if the argument should be made
921  of new values or of progtram variables because up to now the
922  two are the same, except when printed out. */
924  sc_base(sc) = vect_add_variable(b, (Variable) v_new);
925  sc_base(sc) = vect_add_variable(sc_base(sc), (Variable) v_old);
926  sc_dimension(sc) = base_dimension(sc_base(sc));
927  }
928  else
929  pips_internal_error("Entity \"%s\" has no values.", entity_name(var));
930  }
931 
932  return tf;
933 }
934 
935 /* Move arguments and predicate of t2 into t1, free old arguments and
936  predicate of t1, free what's left of t2. This is used to perform a side
937  effect on an argument when a function allocates a new transformer to
938  return a result. t2 should not be used after a call to move_transformer() */
940 {
941  pips_assert("t1 is consistent on entry", transformer_consistency_p(t1));
942  pips_assert("t2 is consistent on entry", transformer_consistency_p(t2));
943 
947 
951  predicate_system(transformer_relation(t2))= SC_UNDEFINED;
952 
953  free_transformer(t2);
954 
955  pips_assert("t1 is consistent on exit", transformer_consistency_p(t1));
956 
957  return t1;
958 }
959 
960 /* Is value v used with a non-zero coefficient by the equations of
961  * transformer t?
962  */
964 {
967 }
968 
969 /* Is value v used with a non-zero coefficient by the inequalities of
970  * transformer t?
971  */
973 {
976 }
void free_transformer(transformer p)
Definition: ri.c:2616
transformer make_transformer(list a1, predicate a2)
Definition: ri.c:2649
bool transformer_defined_p(transformer p)
Definition: ri.c:2626
predicate make_predicate(Psysteme a1)
Definition: ri.c:1820
void free_predicate(predicate p)
Definition: ri.c:1787
transformer copy_transformer(transformer p)
TRANSFORMER.
Definition: ri.c:2613
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
bool entity_null_locations_p(entity e)
test if an entity is the NULL POINTER
bool entity_stub_sink_p(entity e)
test if an entity is a stub sink for a formal parameter e.g.
void free_arguments(cons *args)
Definition: arguments.c:218
bool entity_is_argument_p(entity e, cons *args)
Definition: arguments.c:150
cons * arguments_add_entity(cons *a, entity e)
Definition: arguments.c:85
#define VALUE_ZERO
#define VALUE_MONE
int Value
#define VALUE_ONE
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
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
Pbase vect_add_variable(Pbase b, Variable v)
package vecteur - routines sur les bases
Definition: base.c:61
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_general_consistency_p(transformer tf, bool is_weak)
Definition: basic.c:632
transformer transformer_add_value_update(transformer t, entity v)
Add an update of variable v to t (a value cannot be updated)
Definition: basic.c:321
transformer transformer_add_identity(transformer tf, entity v)
Definition: basic.c:421
bool transformer_identity_p(transformer t)
Check that t is an identity function.
Definition: basic.c:154
transformer precondition_to_abstract_store(transformer pre)
Get rid of all old values and arguments.
Definition: basic.c:871
transformer transformer_constraint_add(transformer tf, Pvecteur i, bool equality)
Definition: basic.c:348
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
transformer transformer_equalities_add(transformer tf, Pcontrainte eqs)
Definition: basic.c:391
void transformer_free(transformer t)
Definition: basic.c:68
bool transformer_equations_constrain_variable_p(const transformer t, const entity v)
Is value v used with a non-zero coefficient by the equations of transformer t?
Definition: basic.c:963
transformer transformer_add_inequality_with_integer_constraint(transformer tf, entity v, long long int cst, bool less_than_p)
Add the inequality v <= cst or v >= cst.
Definition: basic.c:477
#define TRANSFORMER_CONSISTENCY_P_DEBUG_LEVEL
void old_transformer_free(transformer t)
Definition: basic.c:89
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
bool transformer_argument_weak_consistency_p(transformer t)
Definition: basic.c:556
bool transformer_weak_consistency_p(transformer t)
Interprocedural transformers do not meet all conditions.
Definition: basic.c:626
transformer transformer_inequality_add(transformer tf, Pvecteur i)
Definition: basic.c:375
bool transformer_inequalities_constrain_variable_p(const transformer t, const entity v)
Is value v used with a non-zero coefficient by the inequalities of transformer t?
Definition: basic.c:972
bool value_belongs_to_transformer_space(entity v, transformer tf)
Definition: basic.c:842
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_add_modified_variable_entity(transformer tf, entity var)
FI: like the previous function, but supposed to end up with a consistent transformer.
Definition: basic.c:909
bool transformer_is_rn_p(transformer t)
Check that transformer t is the canonical representation of the whole afine space defined by its basi...
Definition: basic.c:183
transformer transformer_inequalities_add(transformer tf, Pcontrainte ineqs)
Warning:
Definition: basic.c:409
transformer transformer_add_variable_incrementation(transformer t, entity i, Pvecteur incr)
transformer transformer_add_loop_index(transformer t, entity i, Pvecteur incr): add the index increme...
Definition: basic.c:260
bool transformers_consistency_p(list tl)
Definition: basic.c:616
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
bool transformer_consistency_p(transformer t)
FI: I do not know if this procedure should always return or fail when an inconsistency is found.
Definition: basic.c:612
void free_transformers(transformer t,...)
Definition: basic.c:73
transformer transformer_empty()
Allocate an empty transformer.
Definition: basic.c:120
transformer transformer_add_variables_update(transformer t, list vl)
Definition: basic.c:340
transformer transformer_add_equality(transformer tf, entity v1, entity v2)
Add an equality between two values (two variables?)
Definition: basic.c:436
transformer move_transformer(transformer t1, transformer t2)
Move arguments and predicate of t2 into t1, free old arguments and predicate of t1,...
Definition: basic.c:939
void add_value_to_transformer_space(entity v, transformer tf)
Definition: basic.c:859
list transformer_projectable_values(transformer tf)
Definition: basic.c:827
bool transformer_argument_general_consistency_p(transformer t, bool is_weak)
Definition: basic.c:561
bool transformer_is_empty_p(transformer t)
Check that transformer t is the canonical representation of an empty transformer.
Definition: basic.c:172
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
#define CONTRAINTE_UNDEFINED_P(c)
#define contrainte_succ(c)
#define contrainte_vecteur(c)
passage au champ vecteur d'une contrainte "a la Newgen"
#define CONTRAINTE_UNDEFINED
Pcontrainte contrainte_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
bool entities_may_conflict_p(entity e1, entity e2)
Check if two entities may conflict.
Definition: conflicts.c:984
#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
#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
#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 MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
int vect_size(Pvecteur v)
package vecteur - reductions
Definition: reductions.c:47
#define pips_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 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 user_warning(fn,...)
Definition: misc-local.h:262
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
#define same_string_p(s1, s2)
#define dump_transformer(t)
Definition: print.c:355
#define entity_symbolic_p(e)
#define entity_constant_p(e)
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 entity_in_formal_area_p(entity e)
Formal parameters do not use the standard ram storage.
Definition: entity.c:3196
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
#define transformer_undefined
Definition: ri.h:2847
#define TRANSFORMER(x)
TRANSFORMER.
Definition: ri.h:2841
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define entity_storage(x)
Definition: ri.h:2794
#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 predicate_system_(x)
Definition: ri.h:2068
#define storage_return_p(x)
Definition: ri.h:2516
#define predicate_system(x)
Definition: ri.h:2069
struct Ssysteme * Psysteme
void sc_base_add_variable(Psysteme sc, Variable var)
Definition: sc.c:248
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
bool sc_weak_consistent_p(Psysteme sc)
check that sc is well defined, that the numbers of equalities and inequalities are consistent with th...
Definition: sc.c:362
Psysteme sc_empty(Pbase b)
Psysteme sc_empty(Pbase b): build a Psysteme with one unfeasible constraint to define the empty subsp...
Definition: sc_alloc.c:319
void sc_rm(Psysteme ps)
void sc_rm(Psysteme ps): liberation de l'espace memoire occupe par le systeme de contraintes ps;
Definition: sc_alloc.c:277
void sc_add_egalite(Psysteme p, Pcontrainte e)
void sc_add_egalite(Psysteme p, Pcontrainte e): macro ajoutant une egalite e a un systeme p; la base ...
Definition: sc_alloc.c:389
bool sc_empty_p(Psysteme sc)
bool sc_empty_p(Psysteme sc): check if the set associated to sc is the constant sc_empty or not.
Definition: sc_alloc.c:350
void sc_add_inegalite(Psysteme p, Pcontrainte i)
void sc_add_inegalite(Psysteme p, Pcontrainte i): macro ajoutant une inegalite i a un systeme p; la b...
Definition: sc_alloc.c:406
Pcontrainte eq
element du vecteur colonne du systeme donne par l'analyse
Definition: sc_gram.c:108
Psysteme sc_equation_add(Psysteme sc, Pcontrainte c)
The basis of the constraint system is updated.
Definition: sc_insert_eq.c:101
Psysteme sc_constraint_add(Psysteme sc, Pcontrainte c, bool equality)
Definition: sc_insert_eq.c:115
bool sc_inequalities_constrain_variable_p(Psysteme sc, Variable var)
Definition: sc_misc.c:195
bool sc_equations_constrain_variable_p(Psysteme sc, Variable var)
Definition: sc_misc.c:190
#define ifdebug(n)
Definition: sg.c:47
static char * x
Definition: split_file.c:159
struct Scontrainte * succ
Pbase base
Definition: sc-local.h:75
int dimension
Definition: sc-local.h:74
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
struct Svecteur * succ
Definition: vecteur-local.h:92
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
bool transformer_empty_p(transformer t)
If true is returned, the transformer certainly is empty.
Definition: transformer.c:2455
transformer transformer_projection(transformer t, list args)
values in args must be in t's base
Definition: transformer.c:1267
bool old_value_entity_p(entity)
Definition: value.c:936
bool value_entity_p(entity)
Definition: value.c:976
bool intermediate_value_entity_p(entity)
Definition: value.c:955
entity entity_to_new_value(entity)
Definition: value.c:859
bool new_value_entity_p(entity)
the following three functions are directly or indirectly relative to the current module and its value...
Definition: value.c:925
bool entity_has_values_p(entity)
This function could be made more robust by checking the storage of e.
Definition: value.c:911
bool local_temporary_value_entity_p(entity)
Definition: value.c:654
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
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define vecteur_var(v)
#define VECTEUR_NUL
DEFINITION DU VECTEUR NUL.
#define BASE_UNDEFINED_P(b)
#define vecteur_succ(v)
#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_UNDEFINED
#define term_cst(varval)
#define base_dimension(b)
#define BASE_NULLE
MACROS SUR LES BASES.
#define BASE_NULLE_P(b)
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_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
void vect_chg_coeff(Pvecteur *ppv, Variable var, Value val)
void vect_chg_coeff(Pvecteur *ppv, Variable var, Value val): mise de la coordonnee var du vecteur *pp...
Definition: unaires.c:143