PIPS
translation.c
Go to the documentation of this file.
1 /*
2 
3  $Id: translation.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 /* Package regions : Be'atrice Creusillet 11/95
28  *
29  * array_translation
30  * -----------------
31  *
32  * This File contains general purpose functions that compute the
33  * translation of regions from one array to another (e.g. interprocedural
34  * translation).
35  *
36  */
37 
38 #include <stdio.h>
39 #include <string.h>
40 
41 #include <setjmp.h>
42 
43 #include "boolean.h"
44 #include "vecteur.h"
45 #include "contrainte.h"
46 #include "sc.h"
47 #include "sommet.h"
48 #include "ray_dte.h"
49 #include "sg.h"
50 #include "polyedre.h"
51 #include "union.h"
52 
53 #include "genC.h"
54 #include "linear.h"
55 #include "ri.h"
56 #include "effects.h"
57 #include "database.h"
58 #include "constants.h"
59 
60 #include "ri-util.h"
61 #include "effects-util.h"
62 #include "pipsdbm.h"
63 #include "workspace-util.h"
64 #include "resources.h"
65 #include "misc.h"
66 #include "text.h"
67 #include "text-util.h"
68 #include "transformer.h"
69 #include "preprocessor.h"
70 #include "properties.h"
71 #include "prettyprint.h" // for egalite_debug()
72 
73 #include "effects-generic.h"
74 #include "effects-convex.h"
75 
76 #define BACKWARD true
77 #define FORWARD false
78 
79 #define min(a,b) (((a)<(b))?(a):(b))
80 #define max(a,b) (((a)>(b))?(a):(b))
81 
82 
83 /***************************************************** LOCAL DEBUG FUNCTIONS */
84 
85 static void reg_v_debug(v)
86 Pvecteur v;
87 {
89 }
90 
91 static void reg_sc_debug(sc)
92 Psysteme sc;
93 {
95 }
96 
97 /*********************************************************************************/
98 /* STATISTICS */
99 /*********************************************************************************/
100 
101 static bool statistics_p;
102 
103 /* inputs */
104 static int mat_dim_stat[8][8]; /* correspondances between source and target array
105  * number of dimensions */
106 static int vect_size_ratio_stat[4]; /* size ratio after normalization */
107 static int zero_offset_stat; /* number cases in which the offset is nul */
108 
112 
113 /* translation */
114 
116 {
117  int nb_calls;
122 
123 static struct Linearization_Stat
124 {
125  int nb_calls;
126  int exact;
130 
132 {
133  int nb;
134  int exact;
137 
139 {
140  int nb_calls;
142  int exact;
144 
145 static struct Phi_Elimination_Stat
146 {
147  int nb_calls;
149  int exact;
151 
153 {
154  int nb_calls;
156  int exact;
158 
159 
160 /* initialization and closing*/
161 
163 {
164  int i,j;
165 
166  statistics_p = stat_p;
167 
168  if (!statistics_p)
169  return;
170 
171  for (i=0; i<8; i++)
172  for (j=0; j<8; j++)
173  mat_dim_stat[i][j] = 0;
174 
175  for (i=0; i<4; i++)
176  vect_size_ratio_stat[i] = 0;
177 
178  zero_offset_stat = 0;
182 
187 
192 
196 
200 
204 
208 
209 }
210 
211 void
212 region_translation_statistics_close(const char *mod_name, const char *prefix)
213 {
214  FILE *fp;
215  string filename;
216  int i,j,total;
217 
218  if (!statistics_p) return;
219 
220  filename = "inter_trans_stat";
222  mod_name, ".", prefix, "_", filename, 0));
223 
224  fp = safe_fopen(filename, "w");
225  fprintf(fp,"%s", mod_name);
226 
227  /* inputs */
230 
231  for (i=0; i<8; i++)
232  for (j=0; j<8; j++)
233  fprintf(fp, " %d", mat_dim_stat[i][j]);
234 
235  for (i=0; i<4; i++)
236  fprintf(fp, " %d", vect_size_ratio_stat[i]);
237 
238  /* other ratios */
239  for (total = 0, i=0; i<4; i++)
240  total = total + vect_size_ratio_stat[i];
241  fprintf(fp, " %d", scalar_to_array_stat + array_to_array_stat - total);
242 
243  /* translation */
244  fprintf(fp, " %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
249 
254 
258 
262 
266 
270 
271  fprintf(fp,"\n");
272  safe_fclose(fp, filename);
273  free(filename);
274 }
275 
276 /****************************************************************************/
277 /* Local variables and functions to avoid multiple computations */
278 /****************************************************************************/
279 
282 static bool reference_p;
283 static Value offset;
284 static int dim_1, dim_2;
288 
289 static bool dims_array_init(entity array, dimension* dims, int dim_array)
290 {
291  int i;
292  bool dim_assumed;
293 
294  i = 0;
295  dim_assumed = false;
297  if (i == dim_array -1)
298  {
301 
303  {
304  Pvecteur pvup = normalized_linear(nup);
305  Pvecteur pvlo = normalized_linear(nlo);
306 
307  /* FI: special case for the old Fortran habit of using
308  declarations such as D(1) or E(N,1) to declare a
309  pointer to an array of undefined (last) dimension.
310 
311  Such declarations cannot be used for array bound
312  checking.
313 
314  The warning message does not seem to fit the test. */
315  if(!VECTEUR_NUL_P(pvup) && !VECTEUR_NUL_P(pvlo))
316  if (vect_constant_p(pvup) && value_one_p(val_of(pvup)) &&
317  vect_constant_p(pvlo) && value_one_p(val_of(pvlo)))
318  {
319  pips_user_warning("\nvariable (%s): "
320  "last upper dimension equal to lower;"
321  " assuming unbounded upper bound\n",
322  entity_name(array));
323  dim =
327  NIL);
328  dim_assumed = true;
329  }
330  }
331  }
332  dims[i] = dim;
333  i++;
334  }
335 
336  return dim_assumed;
337 }
338 
339 #define IS_EG true
340 #define NOT_EG false
341 
342 #define PHI_FIRST true
343 #define NOT_PHI_FIRST false
344 
346 {
347  Psysteme sc = sc_new();
348  int dim;
349 
350  for (dim=1; dim<=ndim; dim++)
351  {
352  (void) sc_add_phi_equation(&sc, dimension_lower(dims[dim-1]),
353  dim, NOT_EG, NOT_PHI_FIRST);
354  (void) sc_add_phi_equation(&sc, dimension_upper(dims[dim-1]),
355  dim, NOT_EG, PHI_FIRST);
356  }
357 
358  return sc;
359 }
360 
361 
363  entity ent_2, reference rf_2,
364  Value offset_1_m_2)
365 {
366  array_1 = ent_1;
367  array_2 = ent_2;
368  ref_1 = rf_1;
369  ref_2 = rf_2;
370  reference_p =
372  offset = offset_1_m_2;
373 
376 
378 
383 
384  ifdebug(2)
385  {
386  pips_debug(2,"before conversion:\n");
387  fprint_string_Value(stderr, "size_elt_1 = ", size_elt_1);
388  fprint_string_Value(stderr, ", size_elt_2 = ", size_elt_2);
389  fprintf(stderr, "\n");
390  if(!reference_p)
391  fprint_string_Value(stderr, "offset =", offset),
392  fprintf(stderr, "\n");
393  }
394  /* relative sizes of elements */
397  {
402  }
403  else
406  {
410  if (statistics_p)
411  {
414  else if (value_eq(size_elt_1, VALUE_CONST(2)))
416  else if (value_eq(size_elt_1, VALUE_CONST(4)))
418  }
419  }
420  else
423  {
427  if (statistics_p)
428  {
431  else if (value_eq(size_elt_2, VALUE_CONST(2)))
433  else if (value_eq(size_elt_2, VALUE_CONST(4)))
435  }
436  }
437 
439 
440 
441  ifdebug(2)
442  {
443  pips_debug(2,"after conversion:\n");
444  fprint_string_Value(stderr, "size_elt_1 = ", size_elt_1);
445  fprint_string_Value(stderr, ", size_elt_2 = ", size_elt_2);
446  fprintf(stderr, "\n");
447  if(!reference_p)
448  fprint_string_Value(stderr, "offset =", offset),
449  fprintf(stderr, "\n");
450  }
451 
454 
455 }
456 
458 {
459  if (dim_1_assumed)
460  {
461  /* do not free the real declaration */
464  }
465  if (dim_2_assumed)
466  {
467  /* do not free the real declaration */
470  }
471 }
472 
473 /********************************************************************** MISC */
474 
476 {
477  for (; c; c=c->succ)
479  return true;
480  return false;
481 }
482 
483 /* if we have a region like: <A(PHI)-EXACT-{}>
484  * it means that all *declared* elements are touched, although
485  * this is implicit. this occurs with io effects of "PRINT *, A".
486  * in such a case, the declaration constraints MUST be appended
487  * before the translation, otherwise the result might be false.
488  *
489  * potential bug : if the declaration system cannot be generated,
490  * the region should be turned to MAY for the translation?
491  */
493 {
495  Psysteme s = region_system(r);
496 
497  if (entity_scalar_p(v) || region_may_p(r)) return;
498  /* we have an exact array region */
499 
500  pips_debug(5, "considering exact region of array %s\n", entity_name(v));
501 
502  if (!some_phi_variable(sc_egalites(s)) &&
503  !some_phi_variable(sc_inegalites(s)))
504  {
505  pips_debug(7, "appending declaration system\n");
507  }
508 }
509 
510 /***************************************************************** INTERFACE */
511 
513 static Psysteme array_translation_sc(bool *p_exact_translation_p);
514 
515 /* region region_translation(region reg1, entity mod1, reference ref1,
516  * entity ent2, entity mod2, reference ref2,
517  * Pvecteur offset_1_m_2, bool offset_undef_p)
518  * input : a region reg1, from module mod1; a target entity ent2 in module
519  * mod2 (it is possible to have mod1 = mod2 for equivalences);
520  * references ref1 and ref2 and offset_1_m_2 are provided to
521  * represent the offset between the index of the initial and target
522  * entity; if both entities are in a common or are equivalenced,
523  * then we can only provide offset_1_m_2; when
524  * translating from a formal to a real parameter or from a real to
525  * a formal one, we only know the real reference, the other one being
526  * undefined.
527  * output : a list of regions corresponding to the translation of reg1.
528  * modifies : nothing, reg1 is duplicated.
529  * comment :
530  *
531  * NW:
532  * before calling "region_translation" do
533  *
534  * call "set_interprocedural_translation_context_sc"
535  * (see comment for "set_interprocedural_translation_context_sc" for what
536  * must be done before that is called)
537  *
538  * and "set_backward_arguments_to_eliminate" (for translation formals->reals)
539  * or "set_forward_arguments_to_eliminate"
540  *
541  * like this:
542  *
543  * call call_site;
544  * entity callee;
545  * list real_args;
546  * ...
547  * (set up call to "set_interprocedural_translation_context_sc" as
548  * indicated in its comments)
549  * ...
550  * real_args = call_arguments(call_site);
551  * set_interprocedural_translation_context_sc(callee, real_args);
552  * set_backward_arguments_to_eliminate(callee);
553  *
554  * (that's it, but after the call to "region_translation", don't forget to do:)
555  *
556  * reset_translation_context_sc();
557  * reset_arguments_to_eliminate();
558  * (resets after call to "set_interprocedural_translation_context_sc"
559  * as indicated in its comments)
560  */
562  entity ent_2, entity func_2, reference rf_2,
563  Value offset_1_m_2, bool backward_p)
564 {
565  entity ent_1 = region_entity(reg_1);
566  region reg_2 = region_undefined;
567  Psysteme trans_sc;
568  bool exact_translation_p = true;
569  bool exact_input_p = true;
570 
571  debug_on("REGION_TRANSLATION_DEBUG_LEVEL");
572 
573  pips_debug(1,"initial entity: %s, initial function: %s\n",
574  entity_minimal_name(ent_1), entity_name(func_1));
575  pips_debug(1,"target entity: %s, target function: %s\n",
576  entity_minimal_name(ent_2), entity_name(func_2));
577 
578 
579  pips_assert("something to translate\n",
580  !((ent_1==ent_2) && (func_1== func_2)));
581  pips_assert("one reference only\n",
583  pips_assert("non-zero offset, or one reference\n",
584  value_zero_p(offset_1_m_2) ||
585  (reference_undefined_p(rf_1) && reference_undefined_p(rf_2)) );
586 
587  if ((ent_1==ent_2) && (func_1!=func_2))
588  {
589  reg_2 = region_dup(reg_1);
590  pips_debug(1,"same entities.\n");
591  region_translation_of_predicate(reg_2, func_2);
592  debug_off();
593  return(reg_2);
594  }
595 
596  /* The easiest case first: scalar -> scalar
597  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
598  * An effect to the initial scalar corresponds to an effect on the
599  * target scalar. Even if there is only a partial association (see
600  * FORTRAN standard 17.1), writing to ent1 corresponds to a write
601  * effect on ent2 (either because it is really written, as for
602  * real -> complex, or because it becomes undefined). The only pb
603  * is for OUT regions: if the variable becomes undefined, its value
604  * cannot be exported. This case is too difficult to handle, and
605  * I consider that the value of the variable is exported. BC.
606  */
607 
608  if (entity_scalar_p(ent_1) && entity_scalar_p(ent_2))
609  {
611  reg_2 = make_reference_region(make_reference(ent_2, NIL),
612  copy_action(region_action(reg_1)));
614  debug_off();
615  return reg_2;
616  }
617 
618  if (statistics_p)
619  {
620  if (entity_scalar_p(ent_1) || entity_scalar_p(ent_2))
622  else
624  }
625 
626  ifdebug(1)
627  {
628  pips_debug(1,"initial region: \n");
629  print_region(reg_1);
630  }
631 
632  /* We now consider scalars as arrays with zero dimensions */
633  region_translation_init(ent_1, rf_1, ent_2, rf_2, offset_1_m_2);
634 
635  trans_sc = array_translation_sc(&exact_translation_p);
636 
637  if (!SC_UNDEFINED_P(trans_sc))
638  {
639  trans_sc = sc_safe_append(trans_sc, get_translation_context_sc());
640 
641  ifdebug(2)
642  {
643  pips_debug(2, " translation context system :\n ");
645  pips_debug(2, " translation system :\n ");
646  reg_sc_debug(trans_sc);
647  }
648 
649  reg_2 = region_dup(reg_1);
650 
651  /* As soon as possible: This allows to use variable elimination
652  * without exactness tests when the translation is not exact.
653  */
654  if (!exact_translation_p)
655  {
656  pips_user_warning("bad reshaping between %s and %s.\n",
659  }
660 
662  region_sc_append(reg_2, trans_sc, false);
663 
664  /* test to avoid the call to region_remove_beta_variables in most usual
665  * cases
666  */
668  {
669  if (statistics_p)
670  {
671  exact_input_p = region_exact_p(reg_2);
673  if (exact_input_p) beta_elimination_stat.exact_input++;
674  }
676  if (statistics_p && exact_input_p && region_exact_p(reg_2))
678  }
679 
682  if(cell_preference_p(region_cell(reg_2))) {
683  preference p_2 = cell_preference(region_cell(reg_2));
685  }
686  else
688 
689  if (statistics_p)
690  {
691  exact_input_p = region_exact_p(reg_2);
693  if (exact_input_p) phi_elimination_stat.exact_input++;
694  }
696  if (statistics_p && exact_input_p && region_exact_p(reg_2))
697  {
699  }
701 
702  /* should be unnecessary */
703  trans_sc = region_system(reg_2);
704  trans_sc->base = BASE_NULLE;
705  sc_creer_base(trans_sc);
706  /* sc_nredund(&trans_sc); */
707  region_system_(reg_2) = newgen_Psysteme(trans_sc);
709 
710  psi_to_phi_region(reg_2);
712 
713  if (func_1 != func_2)
714  {
715  if (statistics_p)
716  {
717  exact_input_p = region_exact_p(reg_2);
719  if (exact_input_p) predicate_translation_stat.exact_input++;
720  }
721  region_translation_of_predicate(reg_2, func_2);
722  if (statistics_p && exact_input_p && region_exact_p(reg_2))
725  }
726 
727  if (!reference_p || backward_p == BACKWARD)
728  {
729  Psysteme sd;
730 
732  || get_bool_property("REGIONS_WITH_ARRAY_BOUNDS"))
733  {
735  }
736  else
737  {
738  /* last dim of formals to be ignored if equal?!
739  * because of bug :
740  * SUB S1(X), X(1), CALL S2(X) => Write X(1:1)...
741  * SUB S2(Y), Y(10) Y(1:10) = ...
742  */
744  }
745 
746  region_sc_append_and_normalize(reg_2, sd, 1);
748  }
749  }
750  else
751  {
752  reg_2 = entity_whole_region(array_2, region_action(reg_1));
755  }
756 
757  ifdebug(1)
758  {
759  pips_debug(1,"final region: \n");
760  print_region(reg_2);
761  }
762 
764  debug_off();
765  return reg_2;
766 }
767 
768 /*****************************************************************************/
769 /* INTERFACE FUNCTIONS TO AVOID MULTIPLE COMPUTATIONS */
770 /*****************************************************************************/
771 
772 /* System of constraints representing the relations between formal
773  * and actual parameters.
774  */
775 
776 /* CONTEXT STACK */
777 /* hack to work around the fact that Psysteme is an external type. should
778  * be generalized? bc */
779 #define Psysteme_domain -1
780 DEFINE_LOCAL_STACK(translation_context, Psysteme)
781 
783 {
784  make_translation_context_stack();
785 }
786 
788 {
789  free_translation_context_stack();
790 }
791 
792 /* NW:
793  * before calling
794  * "set_interprocedural_translation_context_sc"
795  * for (entity) module
796  * do:
797  * (see also comments for "module_to_value_mappings")
798  *
799  * module_name = module_local_name(module);
800  * set_current_module_entity(module);
801  * regions_init();
802  *
803  * (the next call is for IN/OUT regions,
804  * otherwise, do get_regions_properties() )
805  *
806  * get_in_out_regions_properties();
807  * set_current_module_statement( (statement)
808  * db_get_memory_resource(DBR_CODE, module_name, true) );
809  * set_cumulated_rw_effects((statement_effects)
810  * db_get_memory_resource(DBR_CUMULATED_EFFECTS, module_name, true));
811  * module_to_value_mappings(module);
812  * set_precondition_map( (statement_mapping)
813  * db_get_memory_resource(DBR_PRECONDITIONS, module_name, true));
814  *
815  * (that's it,
816  * but we musn't forget to reset it all again
817  * after the call to set_interprocedural_translation_context_sc
818  * as below)
819  *
820  * reset_current_module_statement();
821  * reset_cumulated_rw_effects();
822  * reset_precondition_map();
823  * regions_end();
824  * reset_current_module_entity();
825  */
826 void
828 {
829  list /* of entity */ l_formals = module_formal_parameters(callee);
830  int arg_num, n_formals = gen_length(l_formals);
831  Psysteme sc;
832 
833  gen_free_list(l_formals);
834 
835  sc = sc_new();
836 
837  /* if there are more actuals than formals, they are skipped.
838  */
839  for(arg_num = 1;
840  !ENDP(real_args) && arg_num<=n_formals;
841  real_args = CDR(real_args), arg_num++)
842  {
843  entity formal_ent = find_ith_formal_parameter(callee,arg_num);
844  expression real_exp = EXPRESSION(CAR(real_args));
845 
846  if (entity_integer_scalar_p(formal_ent))
847  {
848  normalized n_real_exp = NORMALIZE_EXPRESSION(real_exp);
849 
850  if (normalized_linear_p(n_real_exp)){
851  Pvecteur v1 = normalized_linear(n_real_exp);
852  Pvecteur v2 = vect_new((Variable) formal_ent, VALUE_ONE);
853 
855  vect_rm(v2);
856  }
857 
858  }
859  }
860 
861  base_rm(sc_base(sc));
862  sc_base(sc) = (Pbase) NULL;
863  sc_creer_base(sc);
865 
866 }
867 
868 
870 {
871  translation_context_push(sc);
872 }
873 
875 {
876  return(translation_context_head());
877 }
878 
879 
881 {
882  sc_rm(translation_context_head());
883  translation_context_pop();
884 }
885 
886 
887 ␌
888 /* Formal or actual arguments to eliminate, depending on the direction
889  * of propagation.
890  */
891 
892 static list l_arguments_to_eliminate = NIL;
893 
895 {
897  /* FI: Let's hope it's OK for C as well */
899 
900  FOREACH(ENTITY, var, l_decls)
901  {
902  if (type_variable_p(entity_type(var)) && entity_scalar_p(var))
903  l_arguments_to_eliminate = CONS(ENTITY, var, l_arguments_to_eliminate);
904  }
905 
906 }
907 
909 {
910  l_arguments_to_eliminate = function_formal_parameters(func);
911 }
912 
913 void set_arguments_to_eliminate(list l_args)
914 {
915  l_arguments_to_eliminate = l_args;
916 }
917 
919 {
920  l_arguments_to_eliminate = NIL;
921 }
922 
923 
925 {
926  return l_arguments_to_eliminate;
927 }
928 
929 
930 
931 /*********************************************************************************/
932 /* LOCAL FUNCTIONS: relations between phi and psi variables */
933 /*********************************************************************************/
934 
935 static Psysteme arrays_same_first_dimensions_sc(int *p_ind_max);
936 static Psysteme arrays_last_dims_linearization_sc(int dim_min,
937  bool *p_exact_translation_p);
938 
939 static Psysteme array_translation_sc(bool *p_exact_translation_p)
940 {
941  Psysteme trans_sc;
942  int i;
943 
944  /* First, search for trivial relation between PHI and PSY variables */
945  trans_sc = arrays_same_first_dimensions_sc(&i);
946 
947  ifdebug(3)
948  {
949  pips_debug(3, "same first (%d) dimensions sc:\n", i-1);
950  reg_sc_debug(trans_sc);
951  }
952 
953  /* If we have translated all the dimensions */
954  if (i > max(dim_1, dim_2))
955  {
956  pips_debug(3, "all common dimensions have been translated\n");
958 
959  }
960  else /* much more work must be done */
961  {
962  if (!reference_p || i <= min(dim_1, dim_2))
963  {
964  pips_debug(3, "linearization\n");
965  trans_sc = sc_safe_append
966  (trans_sc,
967  arrays_last_dims_linearization_sc(i, p_exact_translation_p));
968  if (statistics_p && *p_exact_translation_p)
970  }
971  /* for the backward interprocedural propagation only */
972  /* if the formal entity is a scalar variable, or if all common dimensions
973  * have already been translated, then we add the equalities
974  * phi_i = i-th index of the reference or phi_i = lower_bound when
975  * the actual reference has no indices.
976  */
977  /* vraiment utile? n'est-ce pas fait par arrays_last_dims_linearization_sc
978  * de manie`re plus ge'ne'rale ?? Est-ce que ici je n'oublie aps des cas?
979  */
980  else if ((!reference_undefined_p(ref_2)) && (i > dim_1))
981  {
982  bool use_ref_p = reference_indices(ref_2) != NIL;
983 
984  pips_debug(3, "the last equations come from the actual array %s.\n",
985  use_ref_p ? "reference" : "declaration");
986 
988 
989  for (; i <= dim_2; i++)
990  {
991  normalized nind = use_ref_p ?
994 
995  if (normalized_linear_p(nind))
996  {
997  entity psi = make_psi_entity(i);
998  Pvecteur v_ind = vect_new((Variable) psi, VALUE_ONE);
999 
1000  v_ind = vect_substract(v_ind, normalized_linear(nind));
1001  sc_add_egalite(trans_sc, contrainte_make(v_ind));
1002  }
1003  else
1004  {
1005  pips_debug(4, "%d-th %s not linear\n", i,
1006  use_ref_p? "index": "lower bound");
1007  *p_exact_translation_p = false;
1008  if (statistics_p)
1010  }
1011 
1012  } /* for */
1013 
1014  trans_sc->base = BASE_NULLE;
1015  sc_creer_base(trans_sc);
1016 
1017  if (statistics_p && *p_exact_translation_p)
1019  } /* else if */
1020  } /* else */
1021 
1022  return(trans_sc);
1023 }
1024 
1025 /* variables representing the same location in a common are simplified...
1026  * this should/must exists somewhere?
1027  * FC 21/06/2000
1028  */
1029 static void simplify_common_variables(Pcontrainte c)
1030 {
1031  bool changed;
1032 
1033  do
1034  {
1035  Pvecteur v, vp;
1036 
1037  changed = false;
1038  for (v=c->vecteur; v && !changed; v=v->succ)
1039  {
1040  entity var = (entity) var_of(v);
1041  if (var)
1042  {
1043  for (vp=v->succ; vp; vp=vp->succ)
1044  {
1045  entity varp = (entity) var_of(vp);
1046  if (varp && entities_may_conflict_p(var, varp))
1047  {
1048  Value val = val_of(vp);
1049  changed = true;
1050  vect_add_elem(& c->vecteur, (Variable) varp, value_uminus(val));
1051  vect_add_elem(& c->vecteur, (Variable) var, val);
1052  break;
1053  }
1054  }
1055  }
1056  }
1057 
1058  } while (changed);
1059 }
1060 
1061 /* static bool arrays_same_ith_dimension_p(reference array_1_ref,
1062  * entity array_2,
1063  * int i)
1064  * input : an actual array reference as it appears in a call, the
1065  * corresponding formal array (entity), and an array dimension.
1066  * output : true if the dimension is identical for both array (see below),
1067  * false otherwise.
1068  * modifies : nothing.
1069  * comment :
1070  *
1071  * assumptions :
1072  * ~~~~~~~~~~~~~
1073  * 1- i <= dim(array_1) && i <= dim(array_2) (i is a common dimension)
1074  * 2- dimensions [1..i-1] are identical
1075  *
1076  * definition :
1077  * ~~~~~~~~~~~~
1078  * we say that two arrays are identical for dimensions i iff :
1079  * 1- i is a common dimensions (i <= dim(array_1) && i <= dim(array_2)).
1080  * 2- the previous dimensions [1..i-1] are identical.
1081  * 3- the actual reference either has no indices (e.g. A) or the index
1082  * of the i-th dimension is equal to the corresponding lower bound.
1083  * 4- the length of dimension i for both array have the same value.
1084  *
1085  */
1086 static bool arrays_same_ith_dimension_p(int i)
1087 {
1088  bool same_dim = true;
1093 
1094  pips_debug(6, "checking dimension %d.\n", i);
1095 
1096  /* FIRST: check the offset with the current dimension */
1097 
1098  /* If there is a reference, we must verify that the offset of this
1099  * dimension is equal to the lower bound of the declaration.
1100  */
1101  if (reference_p)
1102  {
1103  normalized nind;
1105 
1106  /* if the reference has no indices, then the offset of this dimension
1107  * is equal to the lower bound of the declaration.
1108  */
1109  if (reference_indices(ref) != NIL)
1110  {
1111  normalized ndl = reference_undefined_p(ref_1) ? ndl2: ndl1;
1112 
1114 
1115  if (normalized_linear_p(nind) && normalized_linear_p(ndl))
1116  {
1117  /* nind and ndl are in the same name space */
1118  same_dim = vect_equal(normalized_linear(nind),
1119  normalized_linear(ndl));
1120  if (statistics_p && !same_dim)
1122  }
1123  else
1124  {
1125  same_dim = false;
1127  }
1128  }
1129 
1130  pips_debug(6, "reference: %ssame lower bound.\n",
1131  same_dim? "" : "not ");
1132  }
1133  /* If we know the offset, we must verify that it is a multiple of the size
1134  * of the subarray of dimension i. Else, the dimensions must be considered
1135  * non-equivalent.
1136  */
1137  else
1138  if(value_notzero_p(offset))
1139  {
1140  static Value dim_cumu_1;
1141  static Value dim_cumu_2;
1142 
1143  if (i == 1)
1144  {
1145  dim_cumu_1 = VALUE_ONE;
1146  dim_cumu_2 = VALUE_ONE;
1147  }
1148 
1149  if (normalized_linear_p(ndl1) && normalized_linear_p(ndu1) &&
1151  {
1153  normalized_linear(ndl1));
1155  normalized_linear(ndl2));
1156  if (vect_constant_p(v1) && vect_constant_p(v2))
1157  {
1158  Value p = value_plus(val_of(v1), VALUE_ONE);
1159  value_product(dim_cumu_1, p);
1160  p = value_plus(val_of(v2), VALUE_ONE);
1161  value_product(dim_cumu_2, p);
1162  if (i==1)
1163  {
1164  value_product(dim_cumu_1, size_elt_1);
1165  value_product(dim_cumu_2, size_elt_2);
1166  }
1167  same_dim = value_zero_p(value_mod(offset,dim_cumu_1)) &&
1168  value_zero_p(value_mod(offset,dim_cumu_2));
1169 
1170  if (statistics_p && !same_dim)
1172  }
1173  else
1174  {
1175  same_dim = false;
1177  }
1178  vect_rm(v1);
1179  vect_rm(v2);
1180  }
1181  else
1182  {
1183  same_dim = false;
1185  }
1186  pips_debug(6, "offset: %ssame dimension\n", same_dim? "" : "not ");
1187  }
1188 
1189  /* SECOND: check the size of the current dimension if necessary.
1190  * It is not necessary if the offset is equal to 0, and it is the last
1191  * dimension.
1192  */
1193 
1194  if ( same_dim && !((i==dim_1) && (i==dim_2)) )
1195  {
1196  pips_debug(9, "checking size\n");
1197  if (normalized_linear_p(ndl1) && normalized_linear_p(ndl2) &&
1199  {
1201  normalized_linear(ndl1));
1203  normalized_linear(ndl2));
1204  Pcontrainte c;
1205 
1206  if (i == 1)
1207  {
1208  vect_add_elem(&v1, TCST, VALUE_ONE);
1209  v1 = vect_multiply(v1, size_elt_1);
1210  vect_add_elem(&v2, TCST, VALUE_ONE);
1211  v2 = vect_multiply(v2, size_elt_2);
1212  }
1213 
1214  c = contrainte_make(vect_substract(v1,v2));
1215 
1216  if (CONTRAINTE_NULLE_P(c))
1217  same_dim = true;
1218  else {
1219 
1220  /* if dimensions are declared with common variables,
1221  * several entities represent the same value/location.
1222  * this must be dealt with somewhere!
1223  * maybe this should be handled in some other place?
1224  */
1225  simplify_common_variables(c);
1226 
1227  ifdebug(9) {
1228  pips_debug(9, "linear case: ");
1229  egalite_debug(c);
1230  }
1231 
1233  }
1234 
1235  if (statistics_p && !same_dim)
1237  vect_rm(v1);
1238  vect_rm(v2);
1239  contrainte_free(c);
1240  }
1241  else
1242  {
1243  same_dim = false;
1245  }
1246  pips_debug(6, "size: %ssame %d dimension\n", same_dim? "": "not ", i);
1247  }
1248 
1249  pips_debug(6, "%ssame %d dimension\n", same_dim? "" : "not ", i);
1250  return same_dim;
1251 }
1252 
1253 
1254 
1255 /* static Psysteme arrays_same_first_dimensions_sc(int *p_ind_max)
1256  * input : a non-initialized integer which will represent the rank of the first
1257  * non identical dimension of the arrays array_1 and array_2.
1258  * output : a system of constraints representing the relations between the first
1259  * identical dimensions (see below) of the two arrays, if they are affine.
1260  * modifies : *p_ind_max. after the call, the value of *p_ind_max is equal to the
1261  * index of the first dimension which could not be translated
1262  * *p_ind_max is at least equal to 1.
1263  * comment :
1264  *
1265  * definition :
1266  * ~~~~~~~~~~~~
1267  * we say that two arrays are identical for the dimension i iff :
1268  * 1- i is a common dimensions (i <= dim(array_1) && i <= dim(array_2)).
1269  * 2- the previous dimensions [1..i-1] are identical.
1270  * 3- the actual reference either has no indices (e.g. A) or the index
1271  * of the i-th dimension is equal to the corresponding lower bound;
1272  * or the offset is a multiple of the curretn accumulated sizes.
1273  * 4- the length of dimension i for both array have the same value.
1274  *
1275  * the elements of array_1 are represented using PHI variables, while those of
1276  * array_2 are represented using PSI variables.
1277  *
1278  * algorithm :
1279  * ~~~~~~~~~~~
1280  *
1281  * dim = 1
1282  * while (dim <= ndim(array_1) and dim <= ndim(array_2) and
1283  * dim(array_1) ~ dim (array_2))
1284  * sc = sc inter
1285  * {PHI_dim - lower_bound(array_2, dim) = PSI_dim - lower_bound(array_1,dim)}
1286  * endwhile
1287  *
1288  */
1289 static Psysteme arrays_same_first_dimensions_sc(int *p_ind_max)
1290 {
1291  int common_dim = min(dim_1, dim_2); /* max number of common dimensions */
1292  bool same_shape_p;
1293  int i; /* dimension index */
1294  Psysteme trans_sc = sc_new();
1295 
1297 
1298  i = 1;
1299  same_shape_p = true;
1300  while ((i <= common_dim) && same_shape_p)
1301  {
1302  /* Is the current dimension identical for both arrays? */
1303  same_shape_p = arrays_same_ith_dimension_p(i);
1304  if (same_shape_p)
1305  {
1308 
1309  if (normalized_linear_p(ndl_2) && normalized_linear_p(ndl_1))
1310  {
1311  /* we add the equality phi - ndl_1 = psi - ndl_2 if i != 1
1312  * or s1(phi - ndl_1) + beta_1 = s2(psi - ndl_2) + beta_2
1313  * if i == 1
1314  */
1315 
1316  Pvecteur v_phi = vect_new((char *) make_phi_entity(i), VALUE_ONE);
1317  Pvecteur v_psi = vect_new((char *) make_psi_entity(i), VALUE_ONE);
1318  Pvecteur v_phi_psi;
1319 
1320  v_phi = vect_cl_ofl_ctrl(v_phi, VALUE_MONE, normalized_linear(ndl_1),
1321  NO_OFL_CTRL);
1322  v_psi = vect_cl_ofl_ctrl(v_psi, VALUE_MONE, normalized_linear(ndl_2),
1323  NO_OFL_CTRL);
1324 
1325  if (i == 1 && value_ne(size_elt_1,size_elt_2))
1326  {
1327  /* vect_add_elem(&v_phi, TCST, 1); */
1328  v_phi = vect_multiply(v_phi, size_elt_1);
1329 
1331  {
1332  Pvecteur pv_beta;
1333  entity beta = make_beta_entity(1);
1334 
1335  vect_add_elem(&v_phi, (Variable) beta, VALUE_ONE);
1336 
1337  /* add 0 <= beta_1 <= size_elt_1 - 1 to trans_sc */
1338  pv_beta = vect_make(VECTEUR_NUL,
1339  (Variable) beta, VALUE_MONE,
1340  TCST, VALUE_ZERO);
1341  sc_add_inegalite(trans_sc, contrainte_make(pv_beta));
1342  pv_beta = vect_make(
1343  VECTEUR_NUL, (Variable) beta, VALUE_ONE,
1345  sc_add_inegalite(trans_sc, contrainte_make(pv_beta));
1346  }
1347 
1348  /* vect_add_elem(&v_psi, TCST, 1); */
1349  v_psi = vect_multiply(v_psi, size_elt_2);
1350 
1352  {
1353  Pvecteur pv_beta;
1354  entity beta = make_beta_entity(2);
1355 
1356  vect_add_elem(&v_psi, (Variable) beta, VALUE_ONE);
1357 
1358  /* add 0 <= beta_2 <= size_elt_2 - 1 to trans_sc */
1359  pv_beta = vect_make(VECTEUR_NUL,
1360  (Variable) beta, VALUE_MONE,
1361  TCST, VALUE_ZERO);
1362  sc_add_inegalite(trans_sc, contrainte_make(pv_beta));
1363  pv_beta = vect_make(
1364  VECTEUR_NUL,
1365  (Variable) beta, VALUE_ONE,
1367  sc_add_inegalite(trans_sc, contrainte_make(pv_beta));
1368  }
1369  }
1370 
1371  v_phi_psi = vect_substract(v_phi, v_psi);
1372  vect_rm(v_phi);
1373  vect_rm(v_psi);
1374 
1375  ifdebug(8)
1376  {
1377  pips_debug(8, "dimension %d, translation vector : \n", i);
1378  reg_v_debug(v_phi_psi);
1379  }
1380 
1381  sc_add_egalite(trans_sc, contrainte_make(v_phi_psi));
1382  i += 1;
1383  }
1384  else
1385  {
1386  same_shape_p = false;
1388  }
1389  }
1390  }
1391 
1392  *p_ind_max = i;
1393 
1394  trans_sc->base = BASE_NULLE;
1395  sc_creer_base(trans_sc);
1396 
1397  return(trans_sc);
1398 }
1399 
1400 
1401 /* static Pvecteur reference_last_indices_offset(reference ref, int ind)
1402  * input : an array reference of at least ind dimensions, and an integer
1403  * representing one of the array dimension.
1404  * output : a vector, representing the offset of last dimensions of
1405  * ref, beginning at dimension ind, when it is linear.
1406  * offset = (ind_ind - lb_ind) +
1407  * (ind_{ind+1} - lb_{ind+1})* dim_ind +
1408  * ... +
1409  * (ind_{ind_max} - lb_{ind_max})* dim_ind *... * dim_{ind_max-1}
1410  * returns VECTEUR_UNDEFINED, when the offset is not linear.
1411  * modifies : nothing
1412  * comment :
1413  */
1414 static Pvecteur
1415 reference_last_indices_offset(reference ref, int ind, bool *p_linear_p)
1416 {
1417  int dim = (ref == ref_1)? dim_1 : dim_2;
1418  dimension *dims = (ref == ref_1) ? dims_1 : dims_2;
1419  Value size_elt = (ref == ref_1) ? value_uminus(size_elt_1) : size_elt_2;
1420 
1421  normalized ni, nlb, nub;
1422  Pvecteur pv_ind = (Pvecteur) NULL;
1423  Pvecteur pv_ind_plus_1 = VECTEUR_UNDEFINED;
1424 
1425  pips_assert("feasible index", 0 < ind && ind <=dim);
1426 
1427  /* offset of the last dimensions beginning at ind + 1 */
1428  if (ind < dim)
1429  {
1430  pips_debug(8, "ind = %d, dim = %d\n", ind, dim);
1431  pv_ind_plus_1 = reference_last_indices_offset(ref, ind + 1, p_linear_p);
1432  if (!*p_linear_p) return(VECTEUR_UNDEFINED);
1433  }
1434 
1435  pips_debug(8, "ind = %d, dim = %d", ind, dim);
1436 
1438  nlb = NORMALIZE_EXPRESSION(dimension_lower(dims[ind-1]));
1439 
1440  if (normalized_linear_p(ni) && normalized_linear_p(nlb))
1441  {
1442  Pvecteur vi = normalized_linear(ni);
1443  Pvecteur vb = normalized_linear(nlb);
1444 
1445  ifdebug(8)
1446  {
1447  pips_debug(8, "current index :\n"); reg_v_debug(vi);
1448  pips_debug(8, "current lower bound :\n"); reg_v_debug(vb);
1449  }
1450 
1451  /* we must multiply the offset of the indices beginning at ind + 1
1452  * by the length of the current dimension.
1453  */
1454  if ((ind < dim) && !VECTEUR_UNDEFINED_P(pv_ind_plus_1))
1455  {
1456  nub = NORMALIZE_EXPRESSION(dimension_upper(dims[ind-1]));
1457 
1458  if (normalized_linear_p(nub))
1459  {
1460  Pvecteur vd = vect_substract(normalized_linear(nub), vb);
1461  vect_add_elem(&vd, TCST, VALUE_ONE);
1462 
1463  ifdebug(8)
1464  {
1465  pips_debug(8, "lenght of current dimension :\n");
1466  reg_v_debug(vd);
1467  }
1468 
1469  pv_ind = vect_product(&pv_ind_plus_1, &vd);
1470  if (VECTEUR_UNDEFINED_P(pv_ind))
1471  {
1472  *p_linear_p = false;
1474  }
1475 
1476  }
1477  else
1478  {
1479  *p_linear_p = false;
1481  }
1482 
1483  if (*p_linear_p)
1484  pv_ind = vect_cl_ofl_ctrl(pv_ind, VALUE_ONE,
1485  vect_substract(vi, vb),
1486  NO_OFL_CTRL);
1487  }
1488  else pv_ind = vect_substract(vi, vb);
1489 
1490  } /* if (normalized_linear_p(ni) && normalized_linear_p(nlb)) */
1491 
1492  else
1493  {
1494  *p_linear_p = false;
1496  }
1497 
1498  if (! *p_linear_p)
1499  pv_ind = VECTEUR_UNDEFINED;
1500  else
1501  if (ind == 1) pv_ind = vect_multiply(pv_ind, size_elt);
1502 
1503  if (!VECTEUR_UNDEFINED_P(pv_ind_plus_1)) vect_rm(pv_ind_plus_1);
1504 
1505  ifdebug(8)
1506  {
1507  pips_debug(8, "result:\n"); reg_v_debug(pv_ind);
1508  }
1509 
1510  return(pv_ind);
1511 }
1512 
1513 /* on entry, offset != 0
1514  * recursive build of a pvecteur.
1515  */
1516 static Pvecteur global_to_last_dims_offset(int dim_min, bool *p_linear_p)
1517 {
1518  Pvecteur pv_offset = VECTEUR_UNDEFINED;
1519 
1520  pips_assert("feasible index", 0 < dim_min && dim_min <=dim_1);
1521 
1522  if (dim_min == 1)
1523  return vect_make(VECTEUR_NUL, TCST, offset);
1524 
1525  /* here to avoid assert in case of a scalar entity */
1526 
1527  pv_offset = global_to_last_dims_offset(dim_min - 1, p_linear_p);
1528 
1529  if (*p_linear_p)
1530  {
1531  normalized nlb, nub;
1532  Pvecteur vlb, vub;
1533 
1534  nlb = NORMALIZE_EXPRESSION(dimension_lower(dims_1[dim_min-1]));
1535  nub = NORMALIZE_EXPRESSION(dimension_upper(dims_1[dim_min-1]));
1536 
1537  pips_assert("linear expressions",
1539 
1540  vlb = normalized_linear(nlb);
1541  vub = normalized_linear(nub);
1542 
1543  if (vect_constant_p(vlb) && vect_constant_p(vub))
1544  {
1545  Value dim_size =
1546  value_plus(VALUE_ONE, value_minus(vub->val,vlb->val));
1547  pv_offset = vect_div(pv_offset, dim_size);
1548  }
1549  else
1550  {
1551  *p_linear_p = false;
1552  if (!VECTEUR_UNDEFINED_P(pv_offset))
1553  {
1554  vect_rm(pv_offset);
1555  pv_offset = VECTEUR_UNDEFINED;
1556  }
1558  }
1559  }
1560  return pv_offset;
1561 }
1562 
1563 static Pvecteur last_dims_offset(int dim_min, bool *p_linear_p)
1564 {
1565  Pvecteur pv_offset = VECTEUR_NUL;
1566 
1567  *p_linear_p = true;
1568 
1569  if(reference_p)
1570  {
1572 
1573  if (reference_indices(ref) != NIL)
1574  pv_offset = reference_last_indices_offset(ref, dim_min, p_linear_p);
1575  }
1576  else
1577  {
1578  if (value_notzero_p(offset))
1579  {
1580  /* FC hack around a bug:
1581  this function deal with dims_1[], although dim_min may not be a
1582  valid index... It is not obvious to guess what is actually expected.
1583  */
1584  if (dim_min > dim_1) {
1585  pips_user_warning("tmp hack, fix me please\n!");
1586  *p_linear_p = false;
1587  return VECTEUR_NUL;
1588  }
1589 
1590  pv_offset = global_to_last_dims_offset(dim_min, p_linear_p);
1591  }
1592  }
1593  return pv_offset;
1594 }
1595 
1596 /* static Pvecteur array_partial_subscript_value(entity array, int dim_min, dim_max
1597  * entity (*make_region_entity)(int))
1598  * input : an array entity, a dimension, and a function which returns
1599  * an entity representing a particular dimension given its rank.
1600  * output : a Pvecteur representing the 'subscript value' of the array
1601  * consisting of the dimensions higher (>=) than dim_min of the
1602  * initial array.
1603  * modifies : nothing
1604  * comment : the form of the subsrctip value is :
1605  *
1606  * [PHI_(dim_min) - lb_(dim_min)]
1607  * + [PHI_(dim_min + 1) - lb_(dim_min + 1)] * [ub_(dim_min) - lb_(dim_min)]
1608  * + ...
1609  * + [PHI_(dim_max + 1) - lb_(dim_max + 1)] * [ub_(dim_min) - lb_(dim_min)]
1610  * * ...
1611  * * [ub_(dim_max - 1) - lb_(dim_max - 1)]
1612  *
1613  * where lb stands for lower bound, ub for uper bound and dim_max for
1614  * the number of dimensions of the array.
1615  *
1616  * CAUTION : dim_min must be less or equal than dim_max.
1617  */
1618 static Pvecteur array_partial_subscript_value(entity array, dimension *dims,
1619  int dim_array, int dim_min, int dim_max,
1620  entity (*make_region_entity)(int))
1621 {
1622  Pvecteur v_dim_min = VECTEUR_UNDEFINED;
1623  Pvecteur v_dim_min_plus_1 = VECTEUR_UNDEFINED;
1624  dimension d;
1625  normalized ndl, ndu;
1626 
1627  pips_debug(8, "dim_min = %d, dim_max = %d, dim_array = %d \n",
1628  dim_min, dim_max, dim_array);
1629  pips_assert("dim_max must be less than the dimension of the array\n",
1630  dim_max <= dim_array);
1631  pips_assert("dim_min must be less than dim_max\n", dim_min <= dim_max);
1632 
1633  if (dim_min < dim_max)
1634  {
1635  v_dim_min_plus_1 = array_partial_subscript_value(array, dims, dim_array,
1636  dim_min + 1, dim_max,
1637  make_region_entity);
1638  ifdebug(8)
1639  {
1640  pips_debug(8, "v_dim_min_plus_1 : \n");
1641  reg_v_debug(v_dim_min_plus_1);
1642  }
1643  if (VECTEUR_UNDEFINED_P(v_dim_min_plus_1))
1644  return(VECTEUR_UNDEFINED);
1645  }
1646 
1647  d = dims[dim_min-1];
1650 
1651  if (normalized_linear_p(ndl))
1652  {
1653  /* we must multiply the subscript_value of the dimensions beginning
1654  * at ind + 1 by the length of the current dimension
1655  */
1656  if (dim_min < dim_max)
1657  {
1658  if (normalized_linear_p(ndu))
1659  {
1660  Pvecteur v_dim_min_length =
1662  normalized_linear(ndl));
1663  vect_add_elem(&v_dim_min_length, TCST, VALUE_ONE);
1664 
1665  ifdebug(8)
1666  {
1667  pips_debug(8, "length of current dimension: \n");
1668  reg_v_debug(v_dim_min_length);
1669  }
1670  v_dim_min_plus_1 = vect_product(&v_dim_min_plus_1,
1671  &v_dim_min_length);
1672 
1673  if (VECTEUR_UNDEFINED_P(v_dim_min_plus_1))
1674  {
1675  pips_debug(8, "non linear multiplication\n");
1676  v_dim_min = VECTEUR_UNDEFINED;
1678  }
1679  }
1680  else
1681  {
1682  pips_debug(8, "uper bound not linear \n");
1683  vect_rm(v_dim_min_plus_1);
1684  v_dim_min_plus_1 = VECTEUR_UNDEFINED;
1686  }
1687  }
1688 
1689  if (!VECTEUR_UNDEFINED_P(v_dim_min_plus_1) || (dim_min == dim_max))
1690  {
1691  v_dim_min = vect_new((Variable) make_region_entity(dim_min), VALUE_ONE);
1692  v_dim_min = vect_cl_ofl_ctrl(v_dim_min, VALUE_MONE,
1693  normalized_linear(ndl),
1694  NO_OFL_CTRL);
1695  /* works even if v_dim_min_plus_1 == VECTEUR_UNDEFINED */
1696  /* vect_add(v_dim_min_plus_1, v_dim_min) would not work */
1697  v_dim_min = vect_cl_ofl_ctrl(v_dim_min, VALUE_ONE,
1698  v_dim_min_plus_1, NO_OFL_CTRL);
1699  }
1700 
1701  } /* if (normalized_linear_p(ndl)) */
1702  else
1703  {
1704  pips_debug(8, "lower bound not linear : \n");
1705  v_dim_min = VECTEUR_UNDEFINED;
1707  }
1708 
1709  if (!VECTEUR_UNDEFINED_P(v_dim_min_plus_1)) vect_rm(v_dim_min_plus_1);
1710 
1711  ifdebug(8)
1712  {
1713  pips_debug(8, "result: \n");
1714  reg_v_debug(v_dim_min);
1715  }
1716 
1717  return(v_dim_min);
1718 }
1719 
1720 ␌
1721 /* static Psysteme arrays_last_dims_linearization_sc( int dim_min,
1722  * bool *p_exact_translation_p)
1723  * input : an array reference, an array entity, an integer corresponding to an
1724  * array dimension, and a pointer to a boolean.
1725  * output : the translation systeme from real_ref (PSI variables) to func_ent
1726  * (PHI variables) for the dimensions uper or equal to dim_min; it
1727  * is based on the linearization equation, and the formal_real_sc is
1728  * added. *exact_translation_p is set to true if the translation is exact,
1729  * false otherwise
1730  * modifies : nothing.
1731  * comment : for the moment, only affine linearization equations are handled.
1732  */
1733 static Psysteme arrays_last_dims_linearization_sc(int dim_min,
1734  bool *p_exact_translation_p)
1735 {
1736  Psysteme trans_sc = sc_new();
1738  Pvecteur pv_offset = VECTEUR_UNDEFINED;
1739 
1740  pips_debug(8, " dim_min = %d, dim_1 = %d, dim_2 = %d \n",
1741  dim_min, dim_1, dim_2);
1742  /* pips_assert("dim_min must be less that the dimensions of both arrays.",
1743  (dim_min <= dim_1) && ( dim_min <= dim_2)); */
1744 
1746 
1747  *p_exact_translation_p = true;
1748 
1749  /* subscript_value of first entity */
1750  if (dim_min <= dim_1)
1751  {
1752  pv_1 = array_partial_subscript_value(array_1, dims_1, dim_1, dim_min, dim_1,
1753  make_phi_entity);
1754  ifdebug(6){ pips_debug(6, "array_1: \n"); reg_v_debug(pv_1); }
1755  *p_exact_translation_p = !VECTEUR_UNDEFINED_P(pv_1);
1756  }
1757 
1758  if (*p_exact_translation_p)
1759  {
1760  /* subscript_value of second entity */
1761 
1762  if (dim_min <= dim_2)
1763  {
1764  pv_2 = array_partial_subscript_value(array_2, dims_2, dim_2, dim_min,
1766  ifdebug(6){ pips_debug(6, "array_2: \n"); reg_v_debug(pv_2); }
1767  *p_exact_translation_p = !VECTEUR_UNDEFINED_P(pv_2);
1768  }
1769 
1770  if (*p_exact_translation_p)
1771  {
1772  bool linear_offset_p = true;
1773 
1774  pv_offset = last_dims_offset(dim_min, &linear_offset_p);
1775 
1776  ifdebug(6) { pips_debug(6, "offset: \n"); reg_v_debug(pv_offset);}
1777 
1778  *p_exact_translation_p = linear_offset_p;
1779 
1780  }
1781  }
1782 
1783  if (*p_exact_translation_p)
1784  {
1785  if ((dim_min == 1) && !VECTEUR_UNDEFINED_P(pv_1) &&
1787  {
1788  Pvecteur pv_beta;
1789  entity beta = make_beta_entity(1);
1790 
1791  pv_1 = vect_multiply(pv_1, size_elt_1);
1792  vect_add_elem(&pv_1, (Variable) beta, VALUE_ONE);
1793 
1794  /* add 0 <= beta_1 <= size_elt_1 - 1 to trans_sc */
1795  pv_beta = vect_make(VECTEUR_NUL, (Variable) beta, VALUE_MONE,
1796  TCST, VALUE_ZERO);
1797  sc_add_inegalite(trans_sc, contrainte_make(pv_beta));
1798  pv_beta = vect_make(VECTEUR_NUL, (Variable) beta, VALUE_ONE,
1800  sc_add_inegalite(trans_sc, contrainte_make(pv_beta));
1801  }
1802 
1803  if ((dim_min == 1) && !VECTEUR_UNDEFINED_P(pv_2) &&
1805  {
1806  Pvecteur pv_beta;
1807  entity beta = make_beta_entity(2);
1808 
1809  pv_2 = vect_multiply(pv_2, size_elt_2);
1810  vect_add_elem(&pv_2, (Variable) beta, VALUE_ONE);
1811 
1812  /* add 0 <= beta_1 <= size_elt_1 - 1 to trans_sc */
1813  pv_beta = vect_make(VECTEUR_NUL, (Variable) beta, VALUE_MONE,
1814  TCST, VALUE_ZERO);
1815  sc_add_inegalite(trans_sc, contrainte_make(pv_beta));
1816  pv_beta = vect_make(VECTEUR_NUL, (Variable) beta, VALUE_ONE,
1818  sc_add_inegalite(trans_sc, contrainte_make(pv_beta));
1819  }
1820 
1821  pv_2 = vect_cl_ofl_ctrl(pv_2, VALUE_MONE, pv_offset, NO_OFL_CTRL);
1822  sc_add_egalite(trans_sc, contrainte_make(vect_substract(pv_1, pv_2)));
1823  /* trans_sc = sc_safe_normalize(trans_sc); */
1824  trans_sc->base = BASE_NULLE;
1825  sc_creer_base(trans_sc);
1826  }
1827 
1828  if(!VECTEUR_UNDEFINED_P(pv_1)) vect_rm(pv_1);
1829  if(!VECTEUR_UNDEFINED_P(pv_2)) vect_rm(pv_2);
1830  if(!VECTEUR_UNDEFINED_P(pv_offset)) vect_rm(pv_offset);
1831 
1832  return(trans_sc);
1833 }
1834 
1835 /*********************************************************************************/
1836 /* LOCAL FUNCTIONS: translation of the region predicate into the target function */
1837 /* name space */
1838 /*********************************************************************************/
1839 
1840 
1841 
1842 /* Try to convert an value on a non-local variable into an value
1843  * on a local variable using a guessed name (instead of a location
1844  * identity: M and N declared as COMMON/FOO/M and COMMON/FOO/N
1845  * are not identified as a unique variable/location).
1846  *
1847  * Mo more true: It might also fail to translate variable C:M into A:M if C is
1848  * indirectly called from A thru B and if M is not defined in B.
1849  *
1850  * This routine is not too safe. It accepts non-translatable variable
1851  * as input and does not refuse them, most of the time.
1852  */
1853 static void region_translate_global_value(module, reg, val)
1854 entity module;
1855 region reg;
1856 entity val;
1857 {
1858  storage store = storage_undefined;
1859  ram r = ram_undefined;
1860  entity rf = entity_undefined;
1861  entity section = entity_undefined;
1862 
1863  ifdebug(8)
1864  {
1865  pips_debug(8, "begin v = %s and reg =\n", entity_name(val));
1866  print_region(reg);
1867  }
1868 
1869  if(val == NULL)
1870  {
1871  pips_internal_error("Trying to translate TCST");
1872  return;
1873  }
1874 
1875  if(value_entity_p(val))
1876  {
1877  /* FI: to be modified to account for global values that have a name
1878  * but that should nevertheless be translated on their canonical
1879  * representant; this occurs for non-visible global variables
1880  */
1881  /* FI: to be completed later... 3 December 1993
1882  entity var = value_to_variable(v);
1883  debug(8, "translate_global_value", "%s is translated into %s\n",
1884  entity_name(v), entity_name(e));
1885  transformer_value_substitute(tf, val, e);
1886  */
1887 
1888  pips_debug(8, "No need to translate %s\n",entity_name(val));
1889  return;
1890  }
1891 
1892  pips_debug(8, "Trying to translate %s\n", entity_name(val));
1893 
1894  store = entity_storage(val);
1895  if(!storage_ram_p(store))
1896  {
1897  if(storage_rom_p(store))
1898  {
1899  pips_debug(8, "%s is not translatable: store tag %d\n",
1900  entity_name(val), storage_tag(store));
1901  /* Should it be projected? No, this should occur later for xxx#init
1902  * variables when the xxx is translated. Or before if xxx has been
1903  * translated
1904  */
1905  return;
1906  }
1907  else if(storage_formal_p(store))
1908  {
1909  pips_debug(8, "formal %s is not translatable\n", entity_name(val));
1910  return;
1911  }
1912  /* FC 2001/03/22: some obscure bug workaround...
1913  * The 'return' of a function could be translated into the
1914  * assigned variable? well, it should be added anyway somewhere.
1915  */
1916  else if (storage_return_p(store))
1917  {
1918  pips_debug(8, "return %s does not need to be translated.\n",
1919  entity_name(val));
1920  return;
1921  }
1922  else
1923  {
1924  pips_internal_error("%s is not translatable: store tag %d",
1925  entity_name(val), storage_tag(store));
1926  }
1927  }
1928 
1929  r = storage_ram(store);
1930  rf = ram_function(r);
1931  section = ram_section(r);
1932 
1933  if(rf != module && top_level_entity_p(section))
1934  {
1935  /* must be a common; dynamic and static area must have been
1936  * filtered out before */
1937  entity e;
1938  entity v_init = entity_undefined;
1939  Psysteme sc = SC_UNDEFINED;
1940  Pbase b = BASE_UNDEFINED;
1941 
1942  /* try to find an equivalent entity by its name
1943  (whereas we should use locations) */
1944  /*
1945  e = FindEntity(module_local_name(m),
1946  entity_local_name(v));
1947  e = value_alias(value_to_variable(v));
1948  */
1949  e = value_alias(val);
1950  if((e == entity_undefined) || !same_scalar_location_p(val, e))
1951  {
1952  list l = CONS(ENTITY, val, NIL);
1953  /* no equivalent name found, get rid of val */
1954  ifdebug(8)
1955  {
1956  if (e == entity_undefined)
1957  {
1958  pips_debug(8, "No equivalent for %s in %s: project %s\n",
1960  entity_name(val));
1961  }
1962  else
1963  {
1964  pips_debug(8,
1965  "No equivalent location for %s and %s: project %s\n",
1966  entity_name(val), entity_name(e), entity_name(val));
1967  }
1968  }
1969  if (must_regions_p())
1971  else
1973  gen_free_list(l);
1974  sc = region_system(reg);
1975  base_rm(sc->base);
1976  sc->base = BASE_NULLE;
1977  sc_creer_base(sc);
1978  return;
1979  }
1980 
1981  sc = region_system(reg);
1982  b = sc_base(sc);
1983  if(base_contains_variable_p(b, (Variable) e) )
1984  {
1985  /* e has already been introduced and val eliminated; this happens
1986  * when a COMMON variable is also passed as real argument */
1987  pips_debug(8, "%s has already been translated into %s\n",
1988  entity_name(val), entity_name(e));
1989  /* sc_base_remove_variable(sc,(Variable) val);*/
1990  base_rm(sc->base);
1991  sc->base = BASE_NULLE;
1992  sc_creer_base(sc);
1993  }
1994  else
1995  {
1996  pips_debug(8, "%s is translated into %s\n",
1997  entity_name(val), entity_name(e));
1998  region_value_substitute(reg, val, e);
1999  sc = region_system(reg);
2000  base_rm(sc->base);
2001  sc->base = BASE_NULLE;
2002  sc_creer_base(sc);
2003  }
2004 
2005  v_init = (entity) gen_find_tabulated
2006  (concatenate(entity_name(val), OLD_VALUE_SUFFIX, (char *) NULL),
2007  entity_domain);
2008 
2009  if(v_init != entity_undefined)
2010  {
2011  entity e_init = (entity) gen_find_tabulated
2012  (concatenate(entity_name(e), OLD_VALUE_SUFFIX, (char *) NULL),
2013  entity_domain);
2014 
2015  if(e_init == entity_undefined)
2016  {
2017  /* this cannot happen when the summary transformer of a called
2018  * procedure is translated because the write effect in the callee
2019  * that is implied by v_init existence must have been passed
2020  * upwards and must have led to the creation of e_init
2021  */
2022  /* this should not happen when a caller precondition at a call site
2023  * is transformed into a piece of a summary precondition for
2024  * the callee because v_init becomes meaningless; at the callee's
2025  * entry point, by definition, e == e_init; v_init should have been
2026  * projected before
2027  */
2028  Psysteme r = region_system(reg);
2029 
2030  if(base_contains_variable_p(sc_base(r), (Variable) v_init))
2031  pips_internal_error("Cannot find value %s",
2032  strdup(
2033  concatenate(
2036  entity_local_name(val),
2038  (char *) NULL)));
2039  else
2040  {
2041  /* forget e_init: there is no v_init in tf */
2042  pips_debug(8, "%s is not used in tf\n", entity_name(v_init));
2043  }
2044  }
2045  else
2046  {
2047  pips_debug(8, "%s is translated into %s\n",
2048  entity_name(val), entity_name(e));
2049  region_value_substitute(reg, v_init, e_init);
2050  sc = region_system(reg);
2051  base_rm(sc->base);
2052  sc->base = BASE_NULLE;
2053  sc_creer_base(sc);
2054  }
2055  }
2056  /* else : there is no v_init to worry about; v is not changed in
2057  the caller (or its subtree of callees) */
2058  }
2059  /* else : this value does not need to be translated */
2060 }
2061 
2062 
2063 
2064 /* static void region_translate_global_values(module, reg)
2065  * input : a region, reg, and a module.
2066  * output : nothing.
2067  * modifies : the global values are translated into global values for
2068  * the frame of module.
2069  * comment : same as translate_global_values, but deals with regions
2070  * (projection is not the same)
2071  */
2072 static void region_translate_global_values(module, reg)
2073 entity module;
2074 region reg;
2075 {
2076  Psysteme s = region_system(reg);
2077  /* a copy of sc_base(s) is needed because region_translate_global_value()
2078  modifies it at the same time */
2079  Pbase b = (Pbase) vect_dup(sc_base(s));
2080  Pbase bv;
2081 
2082  pips_debug(8, "initial region: \n%s\n", region_to_string(reg));
2083 
2084 
2085  for(bv = b; bv != NULL; bv = bv->succ)
2086  {
2087  region_translate_global_value(module, reg, (entity) vecteur_var(bv));
2088  }
2089 
2090  base_rm(b);
2091 }
2092 
2093 
2094 
2095 /* static void region_translation_of_predicate(region reg, entity to_func,
2096  * list real_args)
2097  * input : a region, a function towards which the region must be translated,
2098  * and the real arguments of the current call site.
2099  * output : nothing
2100  * modifies : the region reg. The integer scalar variables that appear in the
2101  * predicate of the region are translated into their corresponding
2102  * counterparts in the target function to_func, using the affine
2103  * relations between real and formal parameters when they exist, and
2104  * between common variables in the two functions. When such relations
2105  * don't exist, the variables are simply eliminated. The approximation
2106  * of the region can become may if an elimination is not exact
2107  * (see report E/185).
2108  * comment : Also eliminates global values (commons).
2109  */
2110 static void region_translation_of_predicate(region reg, entity to_func)
2111 {
2113  region_translate_global_values(to_func, reg);
2115 
2116  ifdebug(8)
2117  {
2118  pips_debug(8, "region after translation of globals: \n");
2119  print_region(reg);
2120  }
2121 }
2122 
2124 {
2125  /* FI: regions were are not store regions do not need translation */
2126  if(store_effect_p(eff)) {
2127  ifdebug(8)
2128  {
2129  pips_debug(8, "region before translation: \n");
2130  print_region(eff);
2131  }
2132 
2133  if (!sc_rn_p(region_system(eff)))
2134  {
2135  /* we add the system representing the association between
2136  * actual and formal parameters to the region */
2138 
2139  /* then, we eliminate all the scalar variables that appear in the formal
2140  * parameters */
2141  ifdebug(8)
2142  {
2143  pips_debug(8, "variables to eliminate: \n");
2145  }
2146  if (must_regions_p())
2148  (eff, get_arguments_to_eliminate());
2149  else
2151  (eff, get_arguments_to_eliminate());
2152 
2153 
2155  }
2156 
2157  ifdebug(8)
2158  {
2159  pips_debug(8, "region after translation of arguments: \n");
2160  print_region(eff);
2161  }
2162  }
2163 }
2164 
2165 
2166 
2167 /************************************************** PATH TRANSLATION */
2168 
2169 /** @brief translates a convex memory access path reference from given indices
2170  using an address_of memory access path reference
2171 
2172  This function is used when we want to translate a cell or an effect on a[i][j][k] as input_ref,
2173  knowing that a[i] = &address_of_ref. In this case the list of remaning_input_indices is [j][k].
2174 
2175  @param input_ref is the input convex cell reference
2176  @param input_desc is the descriptor describing the input reference
2177  @param input_remaining_indices is the list of indices from input_ref which have to be translated.
2178 
2179  @param address_of_ref is the convex cell reference giving the output base memory access path.
2180  @param address_of_desc is the descriptor describing address_of_ref.
2181 
2182  @param output_ref is a pointer on the resulting convex reference
2183  @param output_desc is a pointer on the resulting descriptor describing output_ref.
2184  @param exact_p is a pointer on a bool which is set to true if the translation is exact, false otherwise.
2185 
2186  input_remaining_indices does not need to be a copy of a part of the indices of input_ref, because it is not modified.
2187  In a first version of this function, it was replaced by a integer giving the rank of the beginning of this list
2188  in the input_ref indices list. However, in generic_eval_cell_with_points_to,
2189  convex_cell_reference_with_address_of_cell_reference_translation may be called
2190  several times with the same input_ref and rank, so it was more efficient to pass the input_remaning_indices list
2191  directly as an argument.
2192 
2193  */
2195 (reference input_ref, descriptor input_desc,
2196  reference address_of_ref, descriptor address_of_desc,
2197  int nb_common_indices,
2198  reference *output_ref, descriptor *output_desc,
2199  bool *exact_p)
2200 {
2201  Psysteme sc_output = SC_UNDEFINED;
2202 
2203  pips_debug(6, "beginning with input_ref = %s and address_of_ref = %s, nb_common_indices = %d\n",
2204  entity_name(reference_variable(input_ref)), entity_name(reference_variable(address_of_ref)), nb_common_indices);
2205 
2206  *output_ref = copy_reference(address_of_ref);
2207 
2208  if (entity_all_locations_p(reference_variable(address_of_ref)))
2209  {
2210  *output_desc = descriptor_undefined;
2211  *exact_p = false;
2212  }
2213  else
2214  {
2215  *exact_p = true;
2216  int nb_phi_address_of_ref = (int) gen_length(reference_indices(address_of_ref));
2217  list volatile input_remaining_indices = reference_indices(input_ref);
2218  int nb_phi_input_ref = (int) gen_length(input_remaining_indices);
2219 
2220  for(int i = 0; i<nb_common_indices; i++, POP(input_remaining_indices));
2221 
2222  if(!ENDP(input_remaining_indices))
2223  {
2224  Psysteme sc_input = descriptor_convex(input_desc);
2225  int i;
2226 
2227  if (nb_phi_address_of_ref !=0)
2228  {
2229  /* the first index of address_of_ref is added to the last index
2230  of input_ref, and the other indexes of address_of_ref are
2231  appended to those of input_ref
2232  We first check that if the last index of address_of_ref is a field entity
2233  then the first non-common index of input_ref is equal to zero. If not we
2234  issue a warning and return an anywhere effect.
2235  */
2236  expression last_address_of_index =
2237  EXPRESSION(CAR(gen_last(reference_indices(address_of_ref))));
2238 
2239  if(entity_field_p(expression_variable(last_address_of_index)))
2240  {
2241  Psysteme volatile sc = sc_dup(sc_input);
2242  entity phi_first_non_common = make_phi_entity(nb_common_indices+1);
2244  Pvecteur v_phi_first_non_common = vect_new((Variable) phi_first_non_common, VALUE_ONE);
2245  bool feasible = true;
2246  Pvecteur v = vect_substract(v1, v_phi_first_non_common);
2247  vect_rm(v1);
2248  vect_rm(v_phi_first_non_common);
2249  sc_constraint_add(sc, contrainte_make(v), false);
2250 
2252  {
2253  pips_debug(3, "overflow error \n");
2254  feasible = true;
2255  }
2256  TRY
2257  {
2258  feasible = sc_integer_feasibility_ofl_ctrl(sc,
2259  FWD_OFL_CTRL, true);
2261  }
2262  if (feasible)
2263  {
2264  pips_user_warning("potential memory overflow -> returning anywhere\n");
2265  free_reference(*output_ref);
2266  *output_ref = make_reference(entity_all_locations(), NIL);
2267  *output_desc = descriptor_undefined;
2268  *exact_p = false;
2269  }
2270  sc_rm(sc);
2271  }
2272 
2273  if(!entity_all_locations_p(reference_variable(*output_ref)))
2274  {
2275  /* preparing the part of sc_input which is to be added to sc_output */
2276  /* first eliminate common dimensions in sc_input (well a copy, do not modify the original) */
2277  sc_input = sc_dup(sc_input);
2278  if (nb_common_indices >0)
2279  {
2280  list l_phi = phi_entities_list(1,nb_common_indices);
2281  FOREACH(ENTITY,phi, l_phi)
2282  {
2283  bool exact_projection;
2284  sc_input = cell_reference_sc_exact_projection_along_variable(*output_ref, sc_input, phi, &exact_projection);
2285  *exact_p = *exact_p && exact_projection;
2286  }
2287  }
2288 
2289  /* then rename phi_nb_common_indices+1 into psi1 in sc_input */
2290  entity phi_first_non_common = make_phi_entity(nb_common_indices+1);
2291  entity psi1 = make_psi_entity(1);
2292  sc_input = sc_variable_rename(sc_input, (Variable) phi_first_non_common, (Variable) psi1);
2293  ifdebug(8)
2294  {
2295  pips_debug(8, "sc_input after phi_first_non_common variable renaming: \n");
2297  }
2298 
2299  /* then shift other phi variables if necessary */
2300  if (nb_phi_address_of_ref != nb_common_indices + 1)
2301  {
2302  for(i=nb_phi_input_ref; i>(nb_common_indices+1); i--)
2303  {
2304  entity old_phi = make_phi_entity(i);
2305  entity new_phi = make_phi_entity(nb_phi_address_of_ref+i-(nb_common_indices+1));
2306 
2307  pips_debug(8, "renaming %s into %s\n", entity_name(old_phi), entity_name(new_phi));
2308  sc_input = sc_variable_rename(sc_input, (Variable) old_phi, (Variable) new_phi);
2309  }
2310  }
2311 
2312  /* preparing the system of sc_output from sc_address_of */
2313  sc_output = sc_dup(descriptor_convex(address_of_desc));
2314  entity phi_max_output = make_phi_entity(nb_phi_address_of_ref);
2315  entity rho_max_output = make_rho_entity(nb_phi_address_of_ref);
2316 
2317  sc_output = sc_variable_rename(sc_output, (Variable) phi_max_output, (Variable) rho_max_output);
2318 
2319  ifdebug(8)
2320  {
2321  pips_debug(8, "sc_output after variable renaming: \n");
2323  }
2324 
2325  /* then we append sc_input to sc_output
2326  */
2327  sc_output = cell_system_sc_append_and_normalize(sc_output, sc_input, true);
2328 
2329  ifdebug(8)
2330  {
2331  pips_debug(8, "sc_output after appending sc_input: \n");
2333  }
2334 
2335  /* then we add the constraint phi_max_output = psi1 + rho_max_output
2336  and we eliminate psi1 and rho_max_output
2337  */
2338  Pvecteur v_phi_max_output = vect_new((Variable) phi_max_output, VALUE_ONE);
2339  Pvecteur v_psi1 = vect_new((Variable) psi1, VALUE_ONE);
2340  Pvecteur v_rho_max_output = vect_new((Variable) rho_max_output, VALUE_ONE);
2341  v_phi_max_output = vect_substract(v_phi_max_output, v_psi1);
2342  v_phi_max_output = vect_substract(v_phi_max_output, v_rho_max_output);
2343  sc_constraint_add(sc_output, contrainte_make(v_phi_max_output), true);
2344 
2345  bool exact_removal;
2346  sc_output = cell_reference_system_remove_psi_variables(*output_ref, sc_output, &exact_removal);
2347  *exact_p = *exact_p && exact_removal;
2348  sc_output = cell_reference_system_remove_rho_variables(*output_ref, sc_output, &exact_removal);
2349  *exact_p = *exact_p && exact_removal;
2350 
2351  ifdebug(8)
2352  {
2353  pips_debug(8, "sc_output after appending removing psi and rho variables: \n");
2355  }
2356  *output_desc = make_descriptor_convex(sc_output);
2357 
2358  /* finally we must add the additional PHI variables or the field entities
2359  to the indices of the output reference */
2360  for(i = nb_phi_address_of_ref +1; i<nb_phi_address_of_ref + nb_phi_input_ref - nb_common_indices; i++)
2361  {
2362  POP(input_remaining_indices);
2363  expression input_remaining_indices_exp = EXPRESSION(CAR(input_remaining_indices));
2364  if (entity_field_p(expression_variable(input_remaining_indices_exp)))
2365  reference_indices(*output_ref) = gen_nconc(reference_indices(*output_ref),
2366  CONS(EXPRESSION,
2367  copy_expression(input_remaining_indices_exp),
2368  NIL));
2369  else
2370  reference_indices(*output_ref) = gen_nconc(reference_indices(*output_ref),
2371  CONS(EXPRESSION,
2373  NIL));
2374  }
2375  pips_debug(8, "*output_ref after adding phi: %s\n", words_to_string(effect_words_reference(*output_ref)));
2376  } /* if(!anywhere_effect_p(n_eff))*/
2377 
2378  } /* if (nb_phi_address_of_ref !=0) */
2379  else
2380  {
2381  /* here nb_phi_address_of_ref is equal to 0 */
2382  /* if it's a scalar, but not a pointer, output_ref is OK */
2383  /* if it's a pointer, output_ref is equal to input_ref but for the first
2384  non-common dimension, which should be equal to 0 in input_ref (I should check
2385  that as in the previous case).
2386  */
2387  entity output_ent = reference_variable(*output_ref);
2388  type bct = entity_basic_concrete_type(output_ent);
2389 
2390  if (!entity_scalar_p(output_ent) || derived_type_p(bct) || pointer_type_p(bct))
2391  {
2392  sc_output = sc_dup(sc_input);
2393  pips_debug(8, "derived or pointer_type\n");
2394 
2395  /* preparing the part of sc_input which is to be added to sc_output */
2396  /* first eliminate common dimensions in sc_input (well a copy, do not modify the original) */
2397  // sc_input = sc_dup(sc_input);
2398  if (nb_common_indices >0)
2399  {
2400  list l_phi = phi_entities_list(1,nb_common_indices);
2401  FOREACH(ENTITY,phi, l_phi)
2402  {
2403  bool exact_projection;
2404  sc_output = cell_reference_sc_exact_projection_along_variable(*output_ref, sc_output, phi, &exact_projection);
2405  *exact_p = *exact_p && exact_projection;
2406  }
2407  }
2408 
2409  /* first remove the first common phi variable which should be equal to zero */
2410  entity phi_first_non_common = make_phi_entity(nb_common_indices+1);
2411  bool exact_projection;
2412  sc_output = cell_reference_sc_exact_projection_along_variable(*output_ref, sc_output, phi_first_non_common, &exact_projection);
2413  *exact_p = *exact_p && exact_projection;
2414 
2415  /* then rename all the phi variables in reverse order */
2416  for(i=nb_common_indices+2; i<=nb_phi_input_ref; i++)
2417  {
2418  entity old_phi = make_phi_entity(i);
2419  entity new_phi = make_phi_entity(i-(nb_common_indices+1));
2420 
2421  sc_variable_rename(sc_output, old_phi, new_phi);
2422  }
2423  *output_desc = make_descriptor_convex(sc_output);
2424 
2425  /* int output_ref_inds = (int) gen_length(reference_indices(*output_ref));*/
2426  for(int i = 1; i<nb_phi_input_ref-nb_common_indices; i++)
2427  {
2428  POP(input_remaining_indices);
2429  expression input_remaining_indices_exp = EXPRESSION(CAR(input_remaining_indices));
2430  if ( entity_field_p(expression_variable(input_remaining_indices_exp)))
2431  reference_indices(*output_ref) = gen_nconc(reference_indices(*output_ref),
2432  CONS(EXPRESSION, copy_expression(input_remaining_indices_exp), NIL));
2433  else
2434  reference_indices(*output_ref) = gen_nconc( reference_indices(*output_ref),
2435  CONS(EXPRESSION,
2437  NIL));
2438  } /* for */
2439  } /* if (derived_type_p(bct) || pointer_type_p(bct)) */
2440  else
2441  {
2442  *output_desc = make_descriptor_convex(sc_new());
2443  *exact_p = true;
2444  }
2445  }
2446 
2447  } /* if(!ENDP(input_remaining_indices))*/
2448 
2449  } /* else du if (effect_undefined_p(eff_real) || ...) */
2450 
2451 
2452 }
2453 
2454 /** @brief translates a convex memory access path reference from given indices
2455  using a value_of memory access path reference
2456 
2457  This function is used when we want to translate a cell or an effect on a[i][j][k] as input_ref,
2458  knowing that a[i] = value_of_ref. In this case the list of remaning_input_indices is [j][k].
2459 
2460  @param input_ref is the input convex cell reference
2461  @param input_desc is the descriptor describing the input reference
2462  @param input_remaining_indices is the list of indices from input_ref which have to be translated.
2463 
2464  @param value_of_ref is the convex cell reference giving the output base memory access path.
2465  @param value_of_desc is the descriptor describing value_of_ref.
2466 
2467  @param output_ref is a pointer on the resulting convex reference
2468  @param output_desc is a pointer on teh resulting descriptor describing output_ref.
2469  @param exact_p is a pointer on a bool which is set to true if the translation is exact, false otherwise.
2470 
2471  input_remaining_indices does not need to be a copy of a part of the indices of input_ref, because it is not modified.
2472  In a first version of this function, it was replaced by a integer giving the rank of the beginning of this list
2473  in the input_ref indices list. However, in generic_eval_cell_with_points_to,
2474  convex_cell_reference_with_value_of_cell_reference_translation may be called
2475  several times with the same input_ref and rank, so it was more efficient to pass the input_remaning_indices list
2476  directly as an argument.
2477 
2478  */
2480 (reference input_ref, descriptor input_desc,
2481  reference value_of_ref, descriptor value_of_desc,
2482  int nb_common_indices,
2483  reference *output_ref, descriptor *output_desc,
2484  bool *exact_p)
2485 {
2486  pips_debug(8, "input_ref = %s\n", words_to_string(effect_words_reference(input_ref)));
2487  pips_debug(8, "value_of_ref = %s\n", words_to_string(effect_words_reference(value_of_ref)));
2488  pips_debug(8, "nb_common_indices = %d\n", nb_common_indices);
2489 
2490  /* assume exactness */
2491  *exact_p = true;
2492 
2493  /* we do not handle yet the cases where the type of value_of_ref does not match
2494  the type of a[i]. I need a special function to test if types are compatible,
2495  because type_equal_p is much too strict.
2496  moreover the signature of the function may not be adapted in case of the reshaping of a array
2497  of structs into an array of char for instance.
2498  */
2499 
2500  /* first build the output reference */
2501  list input_inds = reference_indices(input_ref);
2502  int nb_phi_input = (int) gen_length(input_inds);
2503 
2504  list value_of_inds = reference_indices(value_of_ref);
2505  int nb_phi_value_of = (int) gen_length(value_of_inds);
2506 
2507  *output_ref = copy_reference(value_of_ref);
2508 
2509  /* we add the indices of the input reference past the nb_common_indices
2510  (they have already be poped out) to the copy of the value_of reference */
2511 
2512  for(int i = 0; i<nb_common_indices; i++, POP(input_inds));
2513 
2514  int i = nb_phi_value_of+1; /* current index to be handled */
2515  FOREACH(EXPRESSION, input_ind, input_inds)
2516  {
2517  if (entity_field_p(expression_variable(input_ind)))
2518  reference_indices(*output_ref) = gen_nconc(reference_indices(*output_ref),
2519  CONS(EXPRESSION,
2520  copy_expression(input_ind),
2521  NIL));
2522  else
2523  reference_indices(*output_ref) = gen_nconc(reference_indices(*output_ref),
2524  CONS(EXPRESSION,
2526  NIL));
2527  i++;
2528  }
2529 
2530  /* Then deal with the output descriptor*/
2531  Psysteme input_sc2 = sc_dup(descriptor_convex(input_desc));
2532  Psysteme value_of_sc = descriptor_convex(value_of_desc);
2533 
2534  Psysteme output_sc = sc_dup(value_of_sc);
2535 
2536  /* preparing the part of sc_input which is to be added to sc_output */
2537  /* first eliminate common dimensions in sc_input (well a copy, do not modify the original) */
2538  if (nb_common_indices >0)
2539  {
2540  list l_phi = phi_entities_list(1,nb_common_indices);
2541  FOREACH(ENTITY,phi, l_phi)
2542  {
2543  bool exact_projection;
2544  input_sc2 = cell_reference_sc_exact_projection_along_variable(input_ref, input_sc2, phi, &exact_projection);
2545  *exact_p = *exact_p && exact_projection;
2546  }
2547  }
2548 
2549  if(nb_phi_value_of - nb_common_indices != 0) /* avoid useless renaming */
2550  {
2551  if (nb_phi_value_of<nb_common_indices)
2552  for(i= nb_common_indices+1; i<=nb_phi_input; i++)
2553  {
2554  entity old_phi = make_phi_entity(i);
2555  entity new_phi = make_phi_entity(nb_phi_value_of+i-nb_common_indices);
2556  pips_debug(8, "case 1: i = %d, nb_phi_value_of+i-nb_common_indices = %d\n",
2557  i, nb_phi_value_of+i-nb_common_indices);
2558  sc_variable_rename(input_sc2, old_phi, new_phi);
2559  }
2560  else
2561  for(i= nb_phi_input; i>nb_common_indices; i--)
2562  {
2563  entity old_phi = make_phi_entity(i);
2564  entity new_phi = make_phi_entity(nb_phi_value_of+i-nb_common_indices);
2565 
2566  pips_debug(8, "case 2: i = %d, nb_phi_value_of+i-nb_common_indices = %d\n",
2567  i, nb_phi_value_of+i-nb_common_indices);
2568  sc_variable_rename(input_sc2, old_phi, new_phi);
2569  }
2570 
2571  }
2572  output_sc = cell_system_sc_append_and_normalize(output_sc, input_sc2, 1);
2573 
2574  *output_desc = make_descriptor_convex(output_sc);
2575  sc_rm(input_sc2);
2576 }
2577 
2579 (cell input_cell, descriptor input_desc,
2580  cell address_of_cell, descriptor address_of_desc,
2581  int nb_common_indices,
2582  cell *output_cell, descriptor * output_desc,
2583  bool *exact_p)
2584 {
2585  reference input_ref = cell_any_reference(input_cell);
2586  reference address_of_ref = cell_any_reference(address_of_cell);
2587  reference output_ref;
2589  address_of_ref, address_of_desc,
2590  nb_common_indices, &output_ref,
2591  output_desc,
2592  exact_p);
2593 
2594  *output_cell = make_cell_reference(output_ref);
2595 }
2596 
2598 (cell input_cell, descriptor input_desc,
2599  cell value_of_cell, descriptor value_of_desc,
2600  int nb_common_indices,
2601  cell *output_cell, descriptor * output_desc,
2602  bool *exact_p)
2603 {
2604  reference input_ref = cell_any_reference(input_cell);
2605  reference value_of_ref = cell_any_reference(value_of_cell);
2606  reference output_ref;
2608  value_of_ref, value_of_desc,
2609  nb_common_indices, &output_ref,
2610  output_desc,
2611  exact_p);
2612 
2613  *output_cell = make_cell_reference(output_ref);
2614 }
cell make_cell_reference(reference _field_)
Definition: effects.c:293
action copy_action(action p)
ACTION.
Definition: effects.c:77
descriptor make_descriptor_convex(Psysteme _field_)
Definition: effects.c:439
void free_reference(reference p)
Definition: ri.c:2050
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
dimension make_dimension(expression a1, expression a2, list a3)
Definition: ri.c:565
void free_dimension(dimension p)
Definition: ri.c:532
reference copy_reference(reference p)
REFERENCE.
Definition: ri.c:2047
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
static entity callee
Definition: alias_pairs.c:62
bool entity_all_locations_p(entity e)
test if an entity is the top of the lattice
entity entity_all_locations()
eturn ANY_MODULE:ANYWHERE (the top of the lattice)
#define CATCH(what)
@ overflow_error
#define UNCATCH(what)
#define TRY
#define VALUE_ZERO
#define int_to_value(i)
end LINEAR_VALUE_IS_INT
#define value_minus(v1, v2)
#define value_notzero_p(val)
#define VALUE_CONST(val)
#define value_uminus(val)
unary operators on values
void const char const char const int
#define value_notone_p(val)
#define value_one_p(val)
#define VALUE_MONE
#define value_ne(v1, v2)
#define value_zero_p(val)
int Value
#define value_eq(v1, v2)
bool operators on values
#define value_division(ref, val)
#define value_product(v, w)
#define value_plus(v1, v2)
binary operators on values
#define VALUE_ONE
#define value_mod(v1, v2)
void fprint_string_Value(FILE *, char *, Value)
Definition: io.c:47
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
void egalite_debug(Pcontrainte c)
#define CONTRAINTE_NULLE_P(c)
contrainte nulle (non contrainte 0 == 0 ou 0 <= 0)
Pcontrainte contrainte_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
Pcontrainte contrainte_free(Pcontrainte c)
Pcontrainte contrainte_free(Pcontrainte c): liberation de l'espace memoire alloue a la contrainte c a...
Definition: alloc.c:184
bool vect_constant_p(Pvecteur)
bool vect_constant_p(Pvecteur v): v contains only a constant term, may be zero
Definition: predicats.c:211
#define NB_MAX_ARRAY_DIM
#define region_any_reference(reg)
To be avoided.
#define region_action(reg)
#define debug_region_consistency(reg)
#define region_system_(reg)
#define region_entity(reg)
#define region_system(reg)
#define region_undefined
#define region_may_p(reg)
#define region_cell(reg)
#define region_approximation_tag(reg)
#define region
simulation of the type region
#define region_exact_p(reg)
static Psysteme array_translation_sc(bool *p_exact_translation_p)
static struct Common_Dimension_Stat common_dimension_stat
static int mat_dim_stat[8][8]
inputs
Definition: translation.c:104
void region_translation_init(entity ent_1, reference rf_1, entity ent_2, reference rf_2, Value offset_1_m_2)
Definition: translation.c:362
static bool dim_2_assumed
Definition: translation.c:287
static Psysteme entity_assumed_declaration_sc(dimension *dims, int ndim)
Definition: translation.c:345
static reference ref_1
Definition: translation.c:281
static void region_translation_close()
Definition: translation.c:457
static struct Remaining_Dimension_Stat remaining_dimension_stat
#define NOT_EG
Definition: translation.c:340
static struct Phi_Elimination_Stat phi_elimination_stat
#define NOT_PHI_FIRST
Definition: translation.c:343
static int zero_offset_stat
size ratio after normalization
Definition: translation.c:107
static struct Predicate_Translation predicate_translation_stat
static bool reference_p
Definition: translation.c:282
void append_declaration_sc_if_exact_without_constraints(region r)
if we have a region like: <A(PHI)-EXACT-{}> it means that all declared elements are touched,...
Definition: translation.c:492
#define PHI_FIRST
Definition: translation.c:342
static int vect_size_ratio_stat[4]
correspondances between source and target array number of dimensions
Definition: translation.c:106
static int scalar_to_scalar_stat
number cases in which the offset is nul
Definition: translation.c:109
static void reg_v_debug(Pvecteur v)
Definition: translation.c:85
void region_translation_statistics_init(bool stat_p)
initialization and closing
Definition: translation.c:162
static void region_translation_of_predicate(region reg, entity to_func)
static Value size_elt_1
Definition: translation.c:285
static bool dim_1_assumed
Definition: translation.c:287
void region_translation_statistics_close(const char *mod_name, const char *prefix)
Definition: translation.c:212
static bool some_phi_variable(Pcontrainte c)
Definition: translation.c:475
static int scalar_to_array_stat
Definition: translation.c:110
static reference ref_2
Definition: translation.c:281
static entity array_2
Definition: translation.c:280
static struct Linearization_Stat linearization_stat
static entity array_1
Local variables and functions to avoid multiple computations
Definition: translation.c:280
static int dim_1
Definition: translation.c:284
static dimension dims_2[NB_MAX_ARRAY_DIM]
Definition: translation.c:286
#define min(a, b)
Definition: translation.c:79
static struct Beta_Elimination_Stat beta_elimination_stat
static void reg_sc_debug(Psysteme sc)
Definition: translation.c:91
static Value size_elt_2
Definition: translation.c:285
static bool dims_array_init(entity array, dimension *dims, int dim_array)
Definition: translation.c:289
static int array_to_array_stat
Definition: translation.c:111
static dimension dims_1[NB_MAX_ARRAY_DIM]
Definition: translation.c:286
static int dim_2
Definition: translation.c:284
#define BACKWARD
Package regions : Be'atrice Creusillet 11/95.
Definition: translation.c:76
static bool statistics_p
STATISTICS
Definition: translation.c:101
static Value offset
Definition: translation.c:283
region region_translation(region reg_1, entity func_1, reference rf_1, entity ent_2, entity func_2, reference rf_2, Value offset_1_m_2, bool backward_p)
region region_translation(region reg1, entity mod1, reference ref1, entity ent2, entity mod2,...
Definition: translation.c:561
#define max(a, b)
Definition: translation.c:80
list function_formal_parameters(entity)
void convex_region_descriptor_translation(effect)
entity make_phi_entity(int)
void set_backward_arguments_to_eliminate(entity)
effect make_reference_region(reference, action)
Psysteme cell_reference_sc_exact_projection_along_variable(reference, Psysteme, entity, bool *)
Psysteme get_translation_context_sc(void)
void region_value_substitute(effect, entity, entity)
bool must_regions_p(void)
void convex_cell_reference_with_address_of_cell_reference_translation(reference, descriptor, reference, descriptor, int, reference *, descriptor *, bool *)
void set_translation_context_sc(Psysteme)
void psi_to_phi_region(effect)
list phi_entities_list(int, int)
effect entity_whole_region(entity, action)
void region_sc_append_and_normalize(effect, Psysteme, int)
void convex_cell_reference_with_value_of_cell_reference_translation(reference, descriptor, reference, descriptor, int, reference *, descriptor *, bool *)
void set_forward_arguments_to_eliminate(void)
void convex_cell_with_address_of_cell_translation(cell, descriptor, cell, descriptor, int, cell *, descriptor *, bool *)
void region_remove_beta_variables(effect)
void set_arguments_to_eliminate(list)
void set_interprocedural_translation_context_sc(entity, list)
void reset_arguments_to_eliminate(void)
bool sc_add_phi_equation(Psysteme *, expression, int, bool, bool)
void region_sc_append(effect, Psysteme, bool)
expression make_phi_expression(int)
reference make_regions_psi_reference(entity)
void region_remove_phi_variables(effect)
entity make_beta_entity(int)
utils.c
effect region_dup(effect)
Psysteme entity_declaration_sc(entity)
Psysteme cell_system_sc_append_and_normalize(Psysteme, Psysteme, int)
string region_to_string(effect)
Psysteme cell_reference_system_remove_psi_variables(reference, Psysteme, bool *)
list get_arguments_to_eliminate(void)
void region_exact_projection_along_parameters(effect, list)
void convex_cell_with_value_of_cell_translation(cell, descriptor, cell, descriptor, int, cell *, descriptor *, bool *)
Psysteme cell_reference_system_remove_rho_variables(reference, Psysteme, bool *)
entity make_psi_entity(int)
void region_non_exact_projection_along_parameters(effect, list)
void set_region_interprocedural_translation(void)
void reset_translation_context_sc(void)
entity make_rho_entity(int)
void reset_region_interprocedural_translation(void)
list effect_words_reference(reference)
prettyprint.c
Definition: prettyprint.c:68
const char * pips_region_user_name(entity)
char * pips_region_user_name(entity ent) output : the name of entity.
Definition: prettyprint.c:169
reference cell_any_reference(cell)
API for reference.
Definition: effects.c:77
bool store_effect_p(effect)
Definition: effects.c:1062
bool vect_contains_phi_p(Pvecteur)
bool vect_contains_phi_p(Pvecteur v) input : a vector output : true if v contains a PHI variable,...
Definition: effects.c:1427
#define cell_reference(x)
Definition: effects.h:469
#define cell_preference(x)
Definition: effects.h:472
#define descriptor_undefined
Definition: effects.h:559
#define descriptor_convex(x)
Definition: effects.h:601
#define cell_preference_p(x)
Definition: effects.h:470
@ is_approximation_may
Definition: effects.h:341
#define newgen_Psysteme(p)
Definition: effects.h:47
FILE * safe_fopen(const char *filename, const char *what)
Definition: file.c:67
int safe_fclose(FILE *stream, const char *filename)
Definition: file.c:77
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
void free(void *)
bool entities_may_conflict_p(entity e1, entity e2)
Check if two entities may conflict.
Definition: conflicts.c:984
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
size_t gen_length(const list l)
Definition: list.c:150
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
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
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
list gen_last(list l)
Return the last element of a list.
Definition: list.c:578
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
void vect_fprint(FILE *f, Pvecteur v, get_variable_name_t variable_name)
void vect_fprint(FILE * f, Pvecteur v, char * (*variable_name)()): impression d'un vecteur creux v su...
Definition: io.c:124
bool vect_equal(Pvecteur v1, Pvecteur v2)
bool vect_equal(Pvecteur v1, Pvecteur v2): test a egalite de deux vecteurs
Definition: reductions.c:278
#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 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 MODULE_SEP_STRING
Definition: naming-local.h:30
const char * entity_minimal_name(entity e)
Do preserve scope informations.
Definition: naming.c:214
void print_arguments(list args)
Definition: naming.c:228
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define DEFINE_LOCAL_STACK(name, type)
void * gen_find_tabulated(const char *, int)
Definition: tabulated.c:218
static char * module
Definition: pips.c:74
string db_get_current_workspace_directory(void)
Definition: workspace.c:96
#define print_region(x)
Definition: print.c:343
static const char * prefix
#define UNBOUNDED_DIMENSION_NAME
Definition: ri-util-local.h:74
#define NORMALIZE_EXPRESSION(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_field_p(entity e)
e is the field of a structure
Definition: entity.c:857
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
bool top_level_entity_p(entity e)
Check if the scope of entity e is global.
Definition: entity.c:1130
entity CreateIntrinsic(string name)
this function does not create an intrinsic function because they must all be created beforehand by th...
Definition: entity.c:1311
entity find_ith_formal_parameter(entity the_fnct, int rank)
This function gives back the ith formal parameter, which is found in the declarations of a call or a ...
Definition: entity.c:1863
Pvecteur vect_product(Pvecteur *pv1, Pvecteur *pv2)
returns a Pvecteur equal to (*pv1) * (*pv2) if this product is linear or NULL otherwise.
Definition: eval.c:1032
expression MakeNullaryCall(entity f)
Creates a call expression to a function with zero arguments.
Definition: expression.c:331
entity expression_variable(expression e)
Definition: expression.c:532
list module_formal_parameters(entity func)
list module_formal_parameters(entity func) input : an entity representing a function.
Definition: module.c:327
bool entity_scalar_p(entity)
The concrete type of e is a scalar type.
Definition: variable.c:1113
expression reference_ith_index(reference, int)
functions for references
Definition: util.c:145
type entity_basic_concrete_type(entity)
retrieves or computes and then returns the basic concrete type of an entity
Definition: type.c:3677
bool same_scalar_location_p(entity, entity)
FI: transferred from semantics (should be used for effect translation as well)
Definition: variable.c:1992
bool pointer_type_p(type)
Check for scalar pointers.
Definition: type.c:2993
bool derived_type_p(type)
Returns true if t is of type struct, union or enum.
Definition: type.c:3104
_int SizeOfElements(basic)
This function returns the length in bytes of the Fortran or C type represented by a basic,...
Definition: size.c:297
int NumberOfDimension(entity)
Definition: size.c:588
bool entity_integer_scalar_p(entity)
for variables (like I), not constants (like 1)! use integer_constant_p() for constants
Definition: variable.c:1130
#define storage_formal_p(x)
Definition: ri.h:2522
#define normalized_linear_p(x)
Definition: ri.h:1779
#define reference_variable(x)
Definition: ri.h:2326
#define storage_tag(x)
Definition: ri.h:2515
#define reference_undefined_p(x)
Definition: ri.h:2303
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define ram_undefined
Definition: ri.h:2221
#define dimension_lower(x)
Definition: ri.h:980
#define type_variable(x)
Definition: ri.h:2949
#define entity_storage(x)
Definition: ri.h:2794
#define code_declarations(x)
Definition: ri.h:784
#define storage_ram_p(x)
Definition: ri.h:2519
#define ram_section(x)
Definition: ri.h:2249
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define entity_undefined
Definition: ri.h:2761
#define expression_undefined
Definition: ri.h:1223
#define entity_name(x)
Definition: ri.h:2790
#define dimension_upper(x)
Definition: ri.h:982
#define reference_indices(x)
Definition: ri.h:2328
#define value_code(x)
Definition: ri.h:3067
#define preference_reference(x)
Definition: ri.h:2102
#define variable_dimensions(x)
Definition: ri.h:3122
#define storage_ram(x)
Definition: ri.h:2521
#define ram_function(x)
Definition: ri.h:2247
#define storage_rom_p(x)
Definition: ri.h:2525
#define entity_type(x)
Definition: ri.h:2792
#define normalized_linear(x)
Definition: ri.h:1781
#define storage_return_p(x)
Definition: ri.h:2516
#define type_variable_p(x)
Definition: ri.h:2947
#define entity_domain
newgen_syntax_domain_defined
Definition: ri.h:410
#define variable_basic(x)
Definition: ri.h:3120
#define storage_undefined
Definition: ri.h:2476
#define entity_initial(x)
Definition: ri.h:2796
Psysteme sc_variable_rename(Psysteme s, Variable v_old, Variable v_new)
Psysteme sc_variable_rename(Psysteme s, Variable v_old, Variable v_new): reecriture du systeme s remp...
Definition: sc.c:157
bool sc_rn_p(Psysteme sc)
bool sc_rn_p(Psysteme sc): check if the set associated to sc is the whole space, rn
Definition: sc_alloc.c:369
void sc_creer_base(Psysteme ps)
void sc_creer_base(Psysteme ps): initialisation des parametres dimension et base d'un systeme lineair...
Definition: sc_alloc.c:129
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
Psysteme sc_new(void)
Psysteme sc_new(): alloue un systeme vide, initialise tous les champs avec des valeurs nulles,...
Definition: sc_alloc.c:55
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
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
bool eq_redund_with_sc_p(Psysteme sc, Pcontrainte eq)
bool eq_redund_with_sc_p(sc, eq) Psysteme sc; Pcontrainte eq;
bool sc_integer_feasibility_ofl_ctrl(Psysteme sc, int ofl_ctrl, bool ofl_res)
Psysteme sc_constraint_add(Psysteme sc, Pcontrainte c, bool equality)
Definition: sc_insert_eq.c:115
Psysteme sc_safe_append(Psysteme s1, Psysteme s2)
Psysteme sc_safe_append(Psysteme s1, Psysteme s2) input : output : calcul de l'intersection des polye...
void sc_fprint(FILE *fp, Psysteme ps, get_variable_name_t nom_var)
void sc_fprint(FILE * f, Psysteme ps, char * (*nom_var)()): cette fonction imprime dans le fichier po...
Definition: sc_io.c:220
void sc_print(Psysteme ps, get_variable_name_t nom_var)
void sc_print()
Definition: sc_io.c:194
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
Psysteme sc_safe_normalize(Psysteme ps)
Psysteme sc_safe_normalize(Psysteme ps) output : ps, normalized.
Pvecteur vect_div(Pvecteur v, Value x)
Pvecteur vect_div(Pvecteur v, Value x): division du vecteur v par le scalaire x, si x est different d...
Definition: scalaires.c:52
Pvecteur vect_multiply(Pvecteur v, Value x)
Pvecteur vect_multiply(Pvecteur v, Value x): multiplication du vecteur v par le scalaire x,...
Definition: scalaires.c:123
#define ifdebug(n)
Definition: sg.c:47
static entity array
Pvecteur vecteur
struct Scontrainte * succ
Pbase base
Definition: sc-local.h:75
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
Value val
Definition: vecteur-local.h:91
struct Svecteur * succ
Definition: vecteur-local.h:92
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
string words_to_string(cons *lw)
Definition: print.c:211
#define OLD_VALUE_SUFFIX
bool value_entity_p(entity)
Definition: value.c:976
entity value_alias(entity)
Static aliasing.
Definition: value.c:1729
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define vecteur_var(v)
#define val_of(varval)
#define VECTEUR_NUL
DEFINITION DU VECTEUR NUL.
#define NO_OFL_CTRL
struct Svecteur * Pbase
#define VECTEUR_UNDEFINED
char *(* get_variable_name_t)(Variable)
Definition: vecteur-local.h:62
struct Svecteur * Pvecteur
#define VECTEUR_NUL_P(v)
#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 FWD_OFL_CTRL
#define BASE_UNDEFINED
#define var_of(varval)
#define BASE_NULLE
MACROS SUR LES BASES.
#define VECTEUR_UNDEFINED_P(v)
Pvecteur vect_make(Pvecteur v, Variable var, Value val,...)
Pvecteur vect_make(v, [var, val,]* 0, val) Pvecteur v; // may be NULL, use assigne anyway Variable va...
Definition: alloc.c:165
Pvecteur vect_dup(Pvecteur v_in)
Pvecteur vect_dup(Pvecteur v_in): duplication du vecteur v_in; allocation de et copie dans v_out;.
Definition: alloc.c:51
Pvecteur vect_new(Variable var, Value coeff)
Pvecteur vect_new(Variable var,Value coeff): allocation d'un vecteur colineaire au vecteur de base va...
Definition: alloc.c:110
void vect_rm(Pvecteur v)
void vect_rm(Pvecteur v): desallocation des couples de v;
Definition: alloc.c:78
Pvecteur vect_substract(Pvecteur v1, Pvecteur v2)
Pvecteur vect_substract(Pvecteur v1, Pvecteur v2): allocation d'un vecteur v dont la valeur est la di...
Definition: binaires.c:75
Pvecteur vect_cl_ofl_ctrl(Pvecteur v, Value lambda, Pvecteur u, int ofl_ctrl)
Pvecteur vect_cl_ofl_ctrl(Pvecteur v, Value lambda, Pvecteur u, int ofl_ctrl): etape d'acculumulation...
Definition: binaires.c:128
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