PIPS
interprocedural.c
Go to the documentation of this file.
1 /*
2 
3  $Id: interprocedural.c 23412 2017-08-09 15:07:09Z irigoin $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 /* package simple effects : Be'atrice Creusillet 5/97
28  *
29  * File: interprocedural.c
30  * ~~~~~~~~~~~~~~~~~~~~~~~
31  *
32  * This File contains functions for the interprocedural computation of simple
33  * effects.
34  */
35 
36 #include <stdio.h>
37 #include <string.h>
38 
39 #include "genC.h"
40 #include "linear.h"
41 #include "ri.h"
42 #include "effects.h"
43 #include "text.h"
44 
45 #include "misc.h"
46 #include "properties.h"
47 #include "text-util.h"
48 #include "ri-util.h"
49 #include "prettyprint.h" // for debugging
50 #include "effects-util.h"
51 
52 #include "effects-generic.h"
53 #include "effects-simple.h"
54 
55 #define min(a,b) (((a)<(b))?(a):(b))
56 #define max(a,b) (((a)>(b))?(a):(b))
57 
58 
59 /*********************************************************** INITIALIZATION */
60 
62  list __attribute__((unused)) real_args,
63  bool __attribute__((unused)) backward_p)
64 {
65 }
66 
68 {
69 }
70 
71 
73 {
74 }
75 
76 /************************************************************** INTERFACES */
77 
78 
79 
80 
81 list /* of effects */
83  entity func,
84  list real_args,
85  list l_eff,
87 {
88  return summary_to_proper_effects(func, real_args, l_eff);
89 }
90 
91 /* To replace the make_sdfi_macro() and its call to macro make_simple_effect() */
93 {
94  // functions that can be pointed by effect_dup_func:
95  // simple_effect_dup
96  // region_dup
97  // copy_effect
98  effect ge = (*effect_dup_func)(eff);
100  //entity v = reference_variable(ger);
101  //type ut = ultimate_type(entity_type(v));
102 
103  /* FI: I want to change this function and preserve indices when they
104  are constant or unbounded. This is needed to extend the effect
105  semantics and to analyze array elements and structure fields and
106  pointer dereferencing. A new property would probably be needed to
107  avoid a disaster, at least with the validation suite... althoug
108  we might be safe with Fortran code...*/
109 
110  /*if(reference_indices(ger) != NIL) { */
111  /* FI: could be rewritten like the other summarization routines,
112  with a check for each subscript expression */
114  {
115  list le = effect_to_sdfi_list(ge);
116  ge = EFFECT(CAR(le));
117  }
118 
119 
120  return ge;
121 }
122 
123 /****************************************************************************/
124 
125 /* list effects_dynamic_elim(list l_reg)
126  *
127  * input : a list of effects.
128  *
129  * output : a list of effects in which effects of dynamic variables
130  * are removed, and in which dynamic integer scalar
131  * variables are eliminated from the predicate. If
132  * parameters are passed by value, direct effects on scalar
133  * are also removed.
134  *
135  * modifies : nothing for direct effects; the effects l_reg initially
136  * contains are copied if necessary. Indirect effects may
137  * have to be changed into anywhere effects.
138  *
139  * comment : this procedure is used to generate summary effects. It is
140  * related to the procedure used to summarize the effects
141  * of a block.
142  *
143  */
145 {
146  list l_res = NIL;
147  list c_eff = list_undefined;
148  bool add_anywhere_write_effect_p = false;
149  bool add_anywhere_read_effect_p = false;
150  bool value_passing_p = c_module_p(get_current_module_entity());
151 
152  for(c_eff = l_eff; !ENDP(c_eff); POP(c_eff)) {
153  effect eff = EFFECT(CAR(c_eff));
154 
155  entity eff_ent = effect_entity(eff);
156  storage eff_s = entity_storage(eff_ent);
157  bool ignore_this_effect = false;
158 
159  ifdebug(4) {
160  pips_debug(4, "current effect for entity \"\%s\":\n",
161  entity_name(eff_ent));
162  print_effect(eff);
163  }
164 
165  if(!any_anywhere_effect_p(eff)) {
166  /* If the reference is a common variable (ie. with storage ram but
167  * not dynamic) or a formal parameter, the effect is not ignored.
168  */
169  switch (storage_tag(eff_s)) {
170  case is_storage_return:
171  pips_debug(5, "return var ignored (%s)\n", entity_name(eff_ent));
172  ignore_this_effect = true;
173  break;
174  case is_storage_ram:
175  {
176  ram r = storage_ram(eff_s);
177  /* FI: heap areas effects should be preserved... */
179  /* || heap_area_p(ram_section(r)) */
180  || stack_area_p(ram_section(r))) {
181  type ut = entity_basic_concrete_type(eff_ent);
183 
184  if(pointer_type_p(ut))
185  if(!ENDP(sl)) {
186  /* Can we convert this effect using the pointer
187  initial value? */
188  /* FI: this should rather be done after a constant
189  pointer analysis but I'd like to improve quickly
190  results with Effects/fulguro01.c */
191  value v = entity_initial(eff_ent);
192 
193  if(value_expression_p(v) && !self_initialization_p(eff_ent)) {
195  /* Save the action before the effect may be changed */
196  list nel, fel;
197 
198  /* re-use an existing function... */
199  nel = c_summary_effect_to_proper_effects(eff, ae);
200  /* Should this effect be preserved? */
201  /* Let's hope we do not loop recursively... */
202  fel = effects_dynamic_elim(nel);
203 
204  if(ENDP(fel)) {
205  ignore_this_effect = true;
206  }
207  else
208  {
209  /* c_summary_to_proper_effects can return
210  several effects, but initially it was
211  designed to return a single effect. I have to
212  rebuild effects_dynamic_elim to take that
213  into account. BC.
214  */
215  eff= EFFECT(CAR(fel));
216  }
217  gen_free_list(nel);
218  gen_free_list(fel);
219 
220  }
221  else {
222  action ac = effect_action(eff);
223  pips_debug(5, "Local pointer \"%s\" is not initialized!\n",
224  entity_name(eff_ent));
225  if(action_write_p(ac))
226  add_anywhere_write_effect_p = true;
227  else
228  add_anywhere_read_effect_p = true;
229  ignore_this_effect = true;
230  }
231  }
232  else {
233  pips_debug(5, "Local pointer \"%s\" can be ignored\n",
234  entity_name(eff_ent));
235  ignore_this_effect = true;
236  }
237  else {
238  pips_debug(5, "dynamic or pointed var ignored (%s)\n",
239  entity_name(eff_ent));
240  ignore_this_effect = true;
241  }
242  }
243  break;
244  }
245  case is_storage_formal:
246  if(value_passing_p) {
248  list inds = reference_indices(r);
249  action ac = effect_action(eff);
250  if(action_write_p(ac) && ENDP(inds))
251  ignore_this_effect = true;
252  }
253  break;
254  case is_storage_rom:
255  if(!entity_special_area_p(eff_ent)
256  && !anywhere_effect_p(eff)
257  // FI: this function does not exist, at least with this name
258  /* && !typed_anywhere_effect_p(eff)*/ )
259  ignore_this_effect = true;
260  break;
261  /* pips_internal_error("bad tag for %s (rom)",
262  entity_name(eff_ent));*/
263  default:
264  pips_internal_error("case default reached");
265  }
266  }
267 
268  if (! ignore_this_effect) /* Eliminate dynamic variables. */ {
269  /* FI: this macro is not flexible enough */
270  /* effect eff_res = make_sdfi_effect(eff); */
272  ifdebug(4) {
273  pips_debug(4, "effect preserved for variable \"\%s\": \n",
274  entity_name(effect_variable(eff_res)));
275  print_effect(eff_res);
276  }
277  l_res = CONS(EFFECT, eff_res, l_res);
278  }
279  else ifdebug(4) {
280  pips_debug(4, "effect removed for variable \"\%s\": \n\t %s\n",
283  }
284  }
285 
286  if(add_anywhere_write_effect_p)
288  if(add_anywhere_read_effect_p)
290 
291  l_res = gen_nreverse(l_res);
292  return(l_res);
293 }
294 
295 
296 /*
297  returns a linear expression giving the size of the n dimension sub-array
298  of array a
299  returns NULL if size of array a is not a linear expression.
300 */
301 static Pvecteur
302 size_of_array(entity a,int n)
303 {
304  Pvecteur size_nm1, size_n;
305 
306  if (n == 0)
307  return(vect_new(TCST, VALUE_ONE));
308 
309  if ((size_nm1 = size_of_array(a, n-1)) != (Pvecteur) NULL)
310  {
314 
315  if (normalized_linear_p(ndl) && normalized_linear_p(ndu))
316  {
319  normalized_linear(ndl));
320  Pvecteur v = vect_add(vd, v1);
321 
322  vect_rm(v1);
323  vect_rm(vd);
324 
325  size_n = vect_product(&size_nm1, &v);
326  }
327  else
328  {
329  vect_rm(size_nm1);
330  size_n = (Pvecteur) NULL;
331  }
332  }
333  else {
334  size_n = (Pvecteur) NULL;
335  }
336 
337  return(size_n);
338 }
339 
340 /*
341  returns a linear expression giving the offset of the n first indices
342  of an array reference.
343  returns (Pvecteur) -1 if the offset is not a linear expression.
344 */
345 static Pvecteur
346 offset_of_reference(reference ref, int n)
347 {
350  int nindices = gen_length(indices);
351  Pvecteur voffset = (Pvecteur) NULL;
352  int idim;
353 
354  pips_assert("offset_of_reference", nindices == 0 || nindices >= n);
355 
356  /* nindices is equal to zero when an array is passed as an argument
357  in a call with no indices:
358  CALL INIT(MAT, N)
359  */
360 
361  if (nindices == 0)
362  return(voffset);
363 
364  for (idim = 1; idim <= n; idim++) {
365  bool non_computable = false;
366  expression index = reference_ith_index(ref, idim);
368  normalized ni, nb;
369 
370  ni = NORMALIZE_EXPRESSION(index);
371  nb = NORMALIZE_EXPRESSION(bound);
372 
374  {
375  Pvecteur vi = normalized_linear(ni);
376  Pvecteur vb = normalized_linear(nb);
377 
378  if (! vect_equal(vi, vb))
379  {
380  Pvecteur v = vect_substract(vi, vb);
381  if (idim > 1)
382  {
383  Pvecteur s = size_of_array(a, idim-1);
384  if ((v = vect_product(&v, &s)) == NULL)
385  {
386  non_computable = true;
387  }
388  }
389  if (! non_computable)
390  {
391  voffset = vect_cl(voffset, VALUE_ONE, v);
392  vect_rm(v);
393  }
394  }
395  }
396  else
397  {
398  non_computable = true;
399  }
400 
401  if (non_computable)
402  {
403  vect_rm(voffset);
404  return((Pvecteur) -1);
405  }
406  }
407  return(voffset);
408 }
409 
410 /* Generate the unknown subscripts for a variable of type depth d */
412 {
413  list ind = NIL;
414  int i = 0;
415 
416  for(i=0; i<d; i++) {
418  ind = CONS(EXPRESSION, e, ind);
419  }
420  return ind;
421 }
422 
423 
424 /* list global_effect_translation(effect ef, entity func)
425  * input : a global or static effect from/to subroutine func.
426  * output : a list of effect, translation of effect ef into effects in
427  * the current subroutine name space.
428  * modifies : nothing.
429  * comment : The corresponding common might not be declared in the caller.
430  * In this case, we translate the effect into an effect on
431  * variables of the first module found in the common variable list.
432  * BC, october 1995.
433  */
434 static list /* of effect */
435 global_effect_translation(
436  effect ef,
437  entity source_func __attribute__ ((unused)),
438  entity target_func)
439 {
440  list l_com_ent, l_tmp, l_new_eff = NIL;
441  entity eff_ent = effect_entity(ef);
442  entity ccommon; /* current common */
443  int eff_ent_size, total_size, eff_ent_begin_offset, eff_ent_end_offset;
444  effect new_eff;
445  bool found = false;
446 
447  pips_debug(5, "target function: %s (local name: %s)\n",
448  entity_name(target_func), module_local_name(target_func));
449  pips_debug(5,"input effect: \n%s\n", effect_to_string(ef));
450 
451  /* If the entity is a top-level entity, no translation;
452  * It is the case for variables dexcribing I/O effects (LUNS).
453  */
454  if (top_level_entity_p(eff_ent))
455  //return CONS(EFFECT, make_sdfi_effect(ef), NIL);
457 
458  if (effects_package_entity_p(eff_ent))
460 
461  /* First, we search if the common is declared in the target function;
462  * if not, we have to deterministically choose an arbitrary function
463  * in which the common is declared. It will be our reference.
464  * By deterministically, I mean that this function shall be chosen whenever
465  * we try to translate from this common to a routine where it is not
466  * declared.
467  */
468  ccommon = ram_section(storage_ram(entity_storage(eff_ent)));
469  l_com_ent = area_layout(type_area(entity_type(ccommon)));
470 
471  pips_debug(5, "common name: %s\n", entity_name(ccommon));
472 
473  for( l_tmp = l_com_ent; !ENDP(l_tmp) && !found; l_tmp = CDR(l_tmp) )
474  {
475  entity com_ent = ENTITY(CAR(l_tmp));
476  if (strcmp(entity_module_name(com_ent),
477  module_local_name(target_func)) == 0)
478  {
479  found = true;
480  }
481  }
482 
483  /* If common not declared in caller, use the subroutine of the first entity
484  * that appears in the common layout. (not really deterministic: I should
485  * take the first name in lexical order. BC.
486  */
487  if(!found)
488  {
489  entity ent = ENTITY(CAR(l_com_ent));
490  target_func = module_name_to_entity(
491  entity_module_name(ent));
492  ifdebug(5)
493  {
494  pips_debug(5, "common not declared in caller,\n"
495  "\t using %s declarations instead\n",
496  entity_name(target_func));
497  }
498  }
499 
500  /* Second, we calculate the offset and size of the effect entity */
501  eff_ent_size = array_size(eff_ent);
502  eff_ent_begin_offset = ram_offset(storage_ram(entity_storage(eff_ent)));
503  eff_ent_end_offset = eff_ent_begin_offset + eff_ent_size - 1;
504 
505  pips_debug(6, "\n\t eff_ent: size = %d, offset_begin = %d,"
506  " offset_end = %d \n",
507  eff_ent_size, eff_ent_begin_offset, eff_ent_end_offset);
508 
509  /* then, we perform the translation */
510  for(total_size = 0; !ENDP(l_com_ent) && (total_size < eff_ent_size);
511  l_com_ent = CDR(l_com_ent))
512  {
513  entity new_ent = ENTITY(CAR(l_com_ent));
514 
515  pips_debug(6, "current entity: %s\n", entity_name(new_ent));
516 
517  if (strcmp(entity_module_name(new_ent),
518  module_local_name(target_func)) == 0)
519  {
520  int new_ent_size = array_size(new_ent);
521  int new_ent_begin_offset =
523  int new_ent_end_offset = new_ent_begin_offset + new_ent_size - 1;
524 
525  pips_debug(6, "\n\t new_ent: size = %d, "
526  "offset_begin = %d, offset_end = %d \n",
527  new_ent_size, new_ent_begin_offset, new_ent_end_offset);
528 
529  if ((new_ent_begin_offset <= eff_ent_end_offset) &&
530  (eff_ent_begin_offset <= new_ent_end_offset ))
531  /* these entities have elements in common */
532  {
533  type new_t = entity_type(new_ent);
534  int new_d = type_depth(new_t);
535  list ind = make_unknown_subscript(new_d);
536 
537  /* if the new entity is entirely contained in the original one
538  */
539  if ((new_ent_begin_offset >= eff_ent_begin_offset) &&
540  (new_ent_end_offset <= eff_ent_end_offset))
541  {
542  new_eff =
544  (make_reference(new_ent, ind), /* ??? memory leak */
548  }
549  /* If they only have some elements in common */
550  else
551  {
552  new_eff =
554  (make_reference(new_ent, ind), /* ??? memory leak */
557  }
558 
559  total_size += min (eff_ent_begin_offset,new_ent_end_offset)
560  - max(eff_ent_begin_offset, new_ent_begin_offset) + 1;
561 
562  l_new_eff = CONS(EFFECT, new_eff, l_new_eff);
563  }
564  }
565  }
566 
567  ifdebug(5)
568  {
569  pips_debug(5, "final effects:\n");
570  print_effects(l_new_eff);
571  }
572 
573  return gen_nreverse(l_new_eff);
574 }
575 
576 static effect
577 translate_array_effect(entity called_func, list real_args, reference real_ref,
578  effect formal_effect)
579 {
580  bool bad_reshaping;
581 
582  action formal_tac = effect_action(formal_effect);
583  tag formal_tap = approximation_tag(effect_approximation(formal_effect));
584 
585  entity formal_var = reference_variable(effect_any_reference(formal_effect));
586  int formal_ndims = NumberOfDimension(formal_var);
587 
588  entity real_var = reference_variable(real_ref);
589  int real_ndims = NumberOfDimension(real_var);
590 
591  effect real_effect = effect_undefined;
592 
593  cons *pc;
594  int ipc;
595 
596  Psysteme equations; /* equations entre parametres et
597  arguments */
598  Pvecteur size_formal; /* taille du tableau formel */
599  Pvecteur size_real; /* taille du sous-tableau reel */
600  Pvecteur offset; /* offset de la reference reelle */
601  Pvecteur ineq; /* contrainte a tester:
602  size_formal+offset < size_real */
603 
604  /* FI: why give up for two n-D arrays? Because there is no offset
605  to compute for the other dimensions, since there is no other
606  dimension, I guess. */
607  if (formal_ndims >= real_ndims)
608  return(effect_undefined);
609 
610  /* build equations linking actual arguments and formal parameters */
611  equations = sc_new();
612  for (ipc = 1, pc = real_args; pc != NIL; pc = CDR(pc), ipc++) {
613  expression ra = EXPRESSION(CAR(pc));
614  entity pf = find_ith_parameter(called_func, ipc);
615 
616  if (entity_integer_scalar_p(pf)) {
618 
619  if (normalized_linear_p(nra)) {
620  Pvecteur v1 = (Pvecteur) normalized_linear(nra);
621  Pvecteur v2 = vect_new((Variable) pf, VALUE_ONE);
622  sc_add_egalite(equations,
624 
625  }
626  }
627  }
628 
629  if (get_debug_level() >= 5) {
630  fprintf(stderr, "\nBinding equations: ");
632  }
633 
634  /*
635  on calcule la taille des tableaux formels et reels,
636  l'offset de la reference, et le vecteur de l'inequation.
637  */
638  size_formal = size_of_array(formal_var, formal_ndims);
639  size_real = size_of_array(real_var, formal_ndims);
640  offset = offset_of_reference(real_ref, formal_ndims);
641  if (get_debug_level() >= 5) {
642  fprintf(stderr, "size of formal: ");
644  fprintf(stderr, "size of real: ");
646  if(offset != (Pvecteur) -1) {
647  fprintf(stderr, "offset: ");
649  }
650  else {
651  fprintf(stderr, "offset: could not be computed\n");
652  }
653  }
654 
655  /* Check that inequality real_size <= formal_size + offset - 1
656  * is not compatible with the binding equations
657  */
658  bad_reshaping = true;
659  if (size_formal != NULL && size_real != NULL && offset != (Pvecteur) -1)
660  {
662  ineq = size_real;
663  vect_add_elem(&ineq, TCST, VALUE_ONE);
664  ineq = vect_cl(ineq, VALUE_MONE, size_formal);
665  vect_rm(size_formal);
666  ineq = vect_cl(ineq, VALUE_MONE, offset);
667  vect_rm(offset);
668 
669  /* on ajoute la contrainte au systeme */
670  ct = contrainte_make(ineq);
671  sc_add_ineg(equations, ct);
672 
673  ifdebug(5) {
674  fprintf(stderr, "contrainte: ");
676  fprintf(stderr, "\nsysteme a prouver: ");
678  }
679 
680  bad_reshaping = false;
681  sc_creer_base(equations);
682  if (!sc_empty_p((equations = sc_normalize(equations)))) {
683  debug(5, "translate_array_effect",
684  "Test feasability for normalized system\n");
685  bad_reshaping = sc_faisabilite(equations);
686  debug(5, "translate_array_effect",
687  "Test feasability for normalized system: %s\n",
688  bool_to_string(bad_reshaping));
689  }
690  else {
691  debug(5, "translate_array_effect",
692  "System could not be normalized\n");
693  }
694  sc_rm(equations);
695  }
696 
697  if (! bad_reshaping) {
698  int i;
699  cons *pdims = NIL;
700 
701  for (i = 1; i <= formal_ndims; i++) {
702  pdims = gen_nconc(pdims, CONS(EXPRESSION,
703  entity_ith_bounds(real_var, i),
704  NIL));
705  }
706 
707  if (reference_indices(real_ref) != NIL) {
708 
709  for (i = formal_ndims+1; i <= real_ndims; i++) {
710  pdims = gen_nconc(pdims,
712  reference_ith_index(real_ref, i),
713  NIL));
714  }
715  }
716  else { /* Il faudrait recuperer la declaration du tableau.
717  * (03/93,yi-qing) */
718  for (i = formal_ndims+1; i <= real_ndims; i++) {
719  pdims = gen_nconc(pdims, CONS(EXPRESSION,
721  NIL));
722  }
723  }
724 
725  real_effect = make_simple_effect(
726  make_reference(real_var, pdims), /* ??? memory leak */
727  copy_action(formal_tac),
728  make_approximation(formal_tap, UU));
729  pips_debug(5, "good reshaping between %s and %s\n",
730  entity_name(real_var), entity_name(formal_var));
731  }
732  else {
733  user_warning("translate_array_effect",
734  "bad reshaping between %s and %s\n",
735  entity_name(real_var), entity_name(formal_var));
736  }
737 
738  return(real_effect);
739 }
740 
741 static effect
742 translate_effect(entity called_func, list real_args, reference real_ref,
743  effect formal_effect)
744 {
745  entity formal_var = reference_variable(effect_any_reference(formal_effect));
746  entity real_var = reference_variable(real_ref);
747 
748  action formal_tac = effect_action(formal_effect);
749  tag formal_tap = approximation_tag(effect_approximation(formal_effect));
750 
751  effect real_effect;
752 
753  ifdebug(8)
754  {
755  pips_debug(8, "Formal effect: %s\n",
756  words_to_string(words_effect(formal_effect)));
757 
758  }
759  if (entity_scalar_p(formal_var))
760  {
761  pips_debug(8, "Scalar formal variable.\n");
762  if (entity_scalar_p(real_var) || !ENDP(reference_indices(real_ref)))
763  real_effect = make_simple_effect
764  (real_ref,
765  copy_action(formal_tac),
766  make_approximation(formal_tap, UU));
767  else
768  {
769  reference eff_ref;
770  list eff_ref_indices = NIL;
771 
772  MAP(DIMENSION, dim,
773  {
774  expression lo_exp = dimension_lower(dim);
775 
776  eff_ref_indices =
777  gen_nconc(eff_ref_indices,
778  CONS(EXPRESSION, lo_exp, NIL));
779 
780  },
782  eff_ref = make_reference(real_var, eff_ref_indices);
783  real_effect = make_simple_effect(
784  eff_ref,
785  copy_action(formal_tac),
786  make_approximation(formal_tap, UU));
787  }
788  }
789  else {
790  pips_debug(8, "Array formal variable: translating.\n");
791  real_effect = translate_array_effect(called_func, real_args,
792  real_ref, formal_effect);
793  }
794 
795  if (real_effect == effect_undefined) {
796  int d = type_depth(entity_type(real_var));
798 
799  pips_debug(8," translation failed\n");
800  /* translation failed; returns the whole real arg */
801  real_effect = make_simple_effect
802  (make_reference(real_var, sl), /* ??? memory leak */
803  copy_action(formal_tac),
805  }
806 
807  ifdebug(8)
808  {
809  pips_debug(8, "Real effect: %s\n",
810  words_to_string(words_effect(real_effect)));
811 
812  }
813 
814  return(real_effect);
815 }
816 
817 
818 
819 /* FC: I developped this function afther noticing that the next one was useless for my purpose.
820  *
821  * FI: it assumes reference passing (check added).
822  */
823 /** @return the list of effect of the callee translated into the caller
824  * name space
825  * @param c, the called function
826  * @param e, the effect to translate
827  */
828 list /* of effect */
830  call c,
831  effect e)
832 {
833  entity var = effect_variable(e);
834  storage st = entity_storage(var);
835  list le = NIL;
836  entity f = call_function(c);
837 
839  // not handled case return an empty list
840  pips_user_warning("not handled case, need to be implemented\n");
841  } else {
842  if (storage_formal_p(st)) {
843  effect res;
844  pips_debug (9, "storage formal case\n");
845  /* find the corresponding argument and returns the reference */
846  int n = formal_offset(storage_formal(st));
848 
849  pips_assert("expression is a reference or read effect",
851  /* FI: a preference is forced here */
856 
857  le = CONS(EFFECT, res, NIL);
858  }
859  else if (storage_ram_p(st)) {
860  pips_debug (9, "storage ram case\n");
861  le = global_effect_translation (e,
862  call_function(c),
864  }
865  }
866  return le;
867 }
868 
869 void check_user_call_site(entity func, list args)
870 {
871  /* check the number of parameters */
872  list l_formals = module_formal_parameters(func);
873  int n_formals = (int) gen_length(l_formals);
874 
875  if ((int) gen_length(args) < n_formals)
876  {
877  /* this is really a user error.
878  * if you move this as a user warning, the pips would drop
879  * effects about unbounded formals... why not? FC.
880  */
881  fprintf(stderr,"%d formal arguments for module %s:\n",
882  n_formals,module_local_name(func));
883  dump_arguments(l_formals);
884  fprintf(stderr,"%zd actual arguments:\n",gen_length(args));
885  print_expressions(args);
886  pips_user_error("\nCall to module %s: "
887  "insufficient number of actual arguments.\n",
888  module_local_name(func));
889  }
890  else if ((int) gen_length(args) > n_formals)
891  {
892  /* This can be survived... */
893  fprintf(stderr,"%d formal arguments for module%s:\n",
894  n_formals,module_local_name(func));
895  dump_arguments(l_formals);
896  fprintf(stderr,"%zd actual arguments:\n",gen_length(args));
897  print_expressions(args);
898 
899  pips_user_warning("\nCall to module %s: "
900  "too many actual arguments.\n",
901  module_local_name(func));
902  }
903  gen_free_list(l_formals), l_formals=NIL;
904 }
905 
906 /* FC: argh! the translation is done the other way around...
907  * from the call effects are derived and checked with summary ones,
908  * while I expected the summary proper effects to be translated
909  * into proper effects considering the call site...
910  * the way it is done makes it useless to any other use
911  * (for instance to translate reduction references)
912  * Thus I have to develop my own function:-(
913  */
914 list /* of effect */
916  list /* of expression */ args,
917  list /* of effect */ func_sdfi)
918 {
919  list pc, le = NIL;
920  int ipc;
921  list l_formals = module_formal_parameters(func);
922  int n_formals = (int) gen_length(l_formals);
923  gen_free_list(l_formals);
924 
925  pips_debug(3, "effects on formals on call to %s\n", entity_name(func));
926 
927  /* Might have been done earlier by the parser thru typing or by
928  flint, but let's make sure that the formal and effective
929  parameter lists are compatible. */
930  check_user_call_site(func, args);
931 
932  /* effets of func on formal variables are translated */
933  for (pc = args, ipc = 1; ! ENDP(pc) && ipc<=n_formals; pc = CDR(pc), ipc++)
934  {
935  expression expr = EXPRESSION(CAR(pc));
936  syntax sexpr = expression_syntax(expr);
937  list la = NULL;
938 
939  if (syntax_call_p(sexpr)) {
940  /* To deal with substring real argument */
941  call c = syntax_call(sexpr);
942  entity f = call_function(c);
943  la = call_arguments(c);
944 
945  if (intrinsic_entity_p(f)
946  && (strcmp(entity_local_name(f), SUBSTRING_FUNCTION_NAME)==0))
947  sexpr = expression_syntax(EXPRESSION(CAR(la)));
948  }
949 
950  if (syntax_reference_p(sexpr))
951  {
952  reference real_ref= syntax_reference(sexpr);
953 
954  MAP(EFFECT, formal_effect,
955  {
956  entity formal_param = effect_entity(formal_effect);
957 
958  if (ith_parameter_p(func, formal_param, ipc))
959  {
960  effect real_effect =
961  translate_effect(func, args, real_ref, formal_effect);
962 
963  le = CONS(EFFECT, real_effect, le);
964  }
965  },
966  func_sdfi);
967  }
968  else {
969  /* check if there is no must write effect */
970  FOREACH(EFFECT, formal_effect, func_sdfi)
971  {
972  entity formal_param = effect_entity(formal_effect);
973 
974  if (ith_parameter_p(func, formal_param, ipc))
975  {
976  if (effect_write_p(formal_effect)) {
977  char * term = NULL;
978 
979  switch(ipc) {
980  case 1: term = "st";
981  break;
982  case 2: term = "nd";
983  break;
984  case 3: term ="rd";
985  break;
986  default:
987  term = "th";
988  }
989 
990  if (effect_exact_p(formal_effect))
992  ("\nmodule %s called by module %s:\n\twrite"
993  " effect on non-variable actual"
994  " parameter thru %d%s formal parameter %s\n",
995  module_local_name(func),
998  ipc, term, entity_local_name(formal_param));
999  else
1001  ("\nmodule %s called by module %s:\n\t"
1002  "possible write effect on non-variable "
1003  "actual parameter thru %d%s "
1004  "formal parameter %s\n",
1005  module_local_name(func),
1008  ipc, term,
1009  entity_local_name(formal_param));
1010  }
1011  }
1012  }
1013 
1014  /* if everything is fine, then the effects are the read effects
1015  * of the expression */
1017  }
1018 
1019  }
1020  pips_debug(3, "effects on statics and globals\n");
1021 /* effets of func on static and global variables are translated */
1022  if (get_bool_property("GLOBAL_EFFECTS_TRANSLATION"))
1023  {
1024  FOREACH(EFFECT, ef, func_sdfi)
1025  {
1027  le = gen_nconc(global_effect_translation
1028  (ef, func, get_current_module_entity()),le);
1029  }
1030  }
1031  else
1032  /* hack for HPFC: no translation of global effects */
1033  {
1034  MAP(EFFECT, ef,
1035  {
1037  le = CONS(EFFECT, make_sdfi_effect(ef), le);
1038 
1039  },
1040  func_sdfi);
1041  }
1042 
1043  return gen_nreverse(le);
1044 }
1045 
1046 /**
1047 
1048  @param l_sum_eff is a list of effects on a C function formal parameter. These
1049  effects must be vissible from the caller, which means that their
1050  reference has at leat one index.
1051  @param real_arg is an expression. It's the real argument corresponding to
1052  the formal parameter which memory effects are represented by l_sum_eff.
1053  @param context is the transformer translating the callee's neame space into
1054  the caller's name space.
1055  @return a list of effects which are the translation of l_sum_eff in the
1056  caller's name space.
1057  */
1059  expression real_arg,
1061 {
1062  list l_eff = NIL; /* the result */
1063 
1064  if (!ENDP(l_sum_eff))
1065  {
1066  syntax real_s = expression_syntax(real_arg);
1067  type real_arg_t = expression_to_type(real_arg);
1068  ifdebug(5)
1069  {
1070  pips_debug(8, "begin for real arg %s, of type %s and effects :\n",
1071  expression_to_string(real_arg),
1072  type_to_string(real_arg_t));
1073  (*effects_prettyprint_func)(l_sum_eff);
1074  }
1075 
1076  switch (syntax_tag(real_s))
1077  {
1078  case is_syntax_reference:
1079  {
1080  reference real_ref = syntax_reference(real_s);
1081  entity real_ent = reference_variable(real_ref);
1082  list real_ind = reference_indices(real_ref);
1083 
1084  /* if it's a pointer or a partially indexed array
1085  * We should do more testing here to check if types
1086  * are compatible... (see effect_array_substitution ?)
1087  */
1088  if (pointer_type_p(real_arg_t) ||
1089  gen_length(real_ind) < type_depth(entity_type(real_ent)))
1090  {
1091  FOREACH(EFFECT, eff, l_sum_eff) {
1092  reference eff_ref = effect_any_reference(eff);
1093  //action eff_act = effect_action(eff);
1094  //list eff_ind = reference_indices(eff_ref);
1095 
1096  pips_debug(8, "pointer type real arg reference\n");
1097 
1098  reference n_eff_ref;
1099  descriptor d;
1100  bool exact_translation_p;
1102  real_ref, descriptor_undefined,
1103  0,
1104  &n_eff_ref, &d,
1105  &exact_translation_p);
1106 
1108  {
1109  // functions that can be pointed by reference_to_effect_func:
1110  // reference_to_simple_effect
1111  // reference_to_convex_region
1112  // reference_to_reference_effect
1113  effect real_eff = (*reference_to_effect_func)(real_ref, copy_action(effect_action(eff)), true);
1114  type real_eff_type = reference_to_type(real_ref);
1115  tag act = effect_write_p(eff)? 'w' : 'r' ;
1117  real_eff_type,
1118  act);
1119  l_eff = gen_nconc(l_eff, l_tmp);
1120  free_effect(real_eff);
1121  free_type(real_eff_type);
1122  free_reference(n_eff_ref);
1123  }
1124  else
1125  {
1126  effect n_eff = make_effect(make_cell(is_cell_reference, n_eff_ref),
1127  copy_action(effect_action(eff)),
1128  exact_translation_p? copy_approximation(effect_approximation(eff)):
1131  l_eff = gen_nconc(l_eff, CONS(EFFECT, n_eff, NIL));
1132  }
1133  } /* FOREACH */
1134  } /* if (pointer_type_p(real_arg_t)) */
1135  else
1136  {
1137  pips_debug(8, "real arg reference is not a pointer and is not a partially indexed array -> NIL \n");
1138 
1139  } /* else */
1140  break;
1141  } /* case is_syntax_reference */
1142  case is_syntax_subscript:
1143  {
1144  bool read_p = false;
1145  bool write_p = false;
1146  pips_user_warning("Subscript not supported yet : returning anywhere effect\n");
1147  FOREACH(EFFECT, eff, l_sum_eff)
1148  {
1149  if (effect_read_p(eff)) read_p = true;
1150  if (effect_write_p(eff)) write_p = true;
1151  }
1152  if (read_p)
1154  if (write_p)
1156  break;
1157  }
1158  case is_syntax_call:
1159  {
1160  call real_call = syntax_call(real_s);
1161  entity real_op = call_function(real_call);
1162  list args = call_arguments(real_call);
1163  effect n_eff = effect_undefined;
1164 
1165  if (ENTITY_ASSIGN_P(real_op))
1166  {
1168  (l_sum_eff, EXPRESSION(CAR(CDR(args))), context);
1169  }
1170  else if(ENTITY_ADDRESS_OF_P(real_op))
1171  {
1172  expression arg1 = EXPRESSION(CAR(args));
1173  //syntax s1 = expression_syntax(arg1);
1174  //reference r1 = syntax_reference(s1);
1175  list l_real_arg = NIL;
1176  bool anywhere_w_p = false;
1177  bool anywhere_r_p = false;
1178 
1179  /* first we compute an effect on the argument of the
1180  * address_of operator (to treat cases like &(n->m))*/
1181  pips_debug(6, "addressing operator case \n");
1182 
1183 
1184  list l_eff1 = NIL;
1185  l_real_arg =
1187  (arg1, &l_eff1, true);
1188 
1189  pips_debug_effects(6, "base effects :%s\n", l_eff1);
1190 
1191  FOREACH(EFFECT, eff1, l_eff1)
1192  {
1193  FOREACH(EFFECT, eff, l_sum_eff) {
1194  reference eff_ref = effect_any_reference(eff);
1195  action eff_act = effect_action(eff);
1196 
1197  pips_debug_effect(6, "current effect :%s\n",eff);
1198 
1199  if ((anywhere_r_p && action_read_p(eff_act))
1200  || (anywhere_w_p && action_write_p(eff_act)))
1201  {
1202  pips_debug(6, "no need to translate, "
1203  "result is already anywhere\n");
1204  }
1205  else
1206  {
1207  if (effect_undefined_p(eff1))
1208  {
1209  n_eff = make_anywhere_effect(copy_action(eff_act));
1210  if (action_read_p(eff_act))
1211  anywhere_r_p = true;
1212  else
1213  anywhere_w_p = true;
1214  }
1215  else
1216  {
1217  reference eff1_ref = effect_any_reference(eff1);
1218  reference n_eff_ref;
1219  descriptor d;
1220  bool exact_translation_p;
1222  eff1_ref, descriptor_undefined,
1223  0,
1224  &n_eff_ref, &d,
1225  &exact_translation_p);
1226  n_eff = make_effect(make_cell(is_cell_reference, n_eff_ref),
1227  copy_action(effect_action(eff)),
1228  exact_translation_p? copy_approximation(effect_approximation(eff)):
1231 
1233  {
1234  if (action_read_p(eff_act))
1235  anywhere_r_p = true;
1236  else
1237  anywhere_w_p = true;
1238  }
1239  }
1240 
1241  l_eff = gen_nconc(l_eff, CONS(EFFECT, n_eff, NIL));
1242  }
1243  } /* FOREACH(EFFECT, eff, l_sum_eff) */
1244  } /* FOREACH(EFFECT, eff1, l_eff1) */
1245  gen_free_list(l_real_arg);
1246  gen_full_free_list(l_eff1);
1247  }
1248  else if(ENTITY_POINT_TO_P(real_op)|| ENTITY_FIELD_P(real_op))
1249  {
1250  list l_real_arg = NIL;
1251  bool anywhere_w_p = false;
1252  bool anywhere_r_p = false;
1253  /* first we compute an effect on the real_arg */
1254 
1255  list l_eff1 = NIL;
1257  (real_arg, &l_eff1, true);
1258 
1259  FOREACH(EFFECT, eff1, l_eff1)
1260  {
1261  FOREACH(EFFECT, eff, l_sum_eff) {
1262  reference eff_ref = effect_any_reference(eff);
1263  list eff_ind = reference_indices(eff_ref);
1264  tag eff_act = effect_action_tag(eff);
1265 
1266  if ((anywhere_r_p && eff_act == is_action_read) || (anywhere_w_p && eff_act == is_action_write))
1267  {
1268  pips_debug(6, "no need to translate, result is already anywhere\n");
1269  }
1270  else
1271  {
1272  if (effect_undefined_p(eff1))
1273  {
1274  n_eff =
1276  if (eff_act == is_action_read)
1277  anywhere_r_p = true;
1278  else
1279  anywhere_w_p = true;
1280  }
1281  else
1282  {
1283  // functions that can be pointed by effect_dup_func:
1284  // simple_effect_dup
1285  // region_dup
1286  // copy_effect
1287  n_eff = (*effect_dup_func)(eff1);
1288  /* memory leaks ? */
1289  effect_approximation(n_eff) =
1291  effect_action(n_eff) =
1292  copy_action(effect_action(eff));
1293  }
1294  /* Then we add the indices of the effect reference */
1295  /* Well this is valid only in the general case :
1296  * we should verify that types are compatible.
1297  */
1298  FOREACH(EXPRESSION, ind, eff_ind)
1299  {
1300  // functions that can be pointed by effect_add_expression_dimension_func:
1301  // simple_effect_add_expression_dimension
1302  // convex_region_add_expression_dimension
1303  (*effect_add_expression_dimension_func)(n_eff, ind);
1304  }
1305  l_eff = gen_nconc(l_eff, CONS(EFFECT, n_eff, NIL));
1306  }
1307  } /* FOREACH(EFFECT, eff, l_sum_eff) */
1308  } /* FOREACH(EFFECT, eff1, l_eff1) */
1309  gen_free_list(l_real_arg);
1310  gen_full_free_list(l_eff1);
1311  }
1312  else if(ENTITY_DEREFERENCING_P(real_op))
1313  {
1314  pips_debug(6, "dereferencing operator case \n");
1315  /* if it's a pointer or a partially indexed array
1316  * We should do more testing here to check if types
1317  * are compatible...
1318  */
1319  if (pointer_type_p(real_arg_t) ||
1320  !ENDP(variable_dimensions(type_variable(real_arg_t))))
1321  {
1322  pips_debug(8, "pointer type real arg\n");
1323  /* first compute the region corresponding to the
1324  * real argument
1325  */
1326  list l_real_eff = NIL;
1327  list l_real_arg =
1329  (real_arg, &l_real_eff, true);
1330 
1331  pips_debug_effects(6, "base effects :\n", l_real_eff);
1332  bool anywhere_w_p = false;
1333  bool anywhere_r_p = false;
1334 
1335  FOREACH(EFFECT, real_eff, l_real_eff)
1336  {
1337  FOREACH(EFFECT, eff, l_sum_eff) {
1338  tag eff_act = effect_action_tag(eff);
1339 
1340  if ((anywhere_r_p && eff_act == is_action_read) || (anywhere_w_p && eff_act == is_action_write))
1341  {
1342  pips_debug(6, "no need to translate, result is already anywhere\n");
1343  }
1344  else
1345  {/* this could easily be made generic BC. */
1346  if(!anywhere_effect_p(real_eff) && store_effect_p(real_eff))
1347  {
1348  reference n_eff_ref;
1349  descriptor n_eff_d;
1350  effect n_eff;
1351  bool exact_translation_p;
1352  // functions that can be pointed by effect_dup_func:
1353  // simple_effect_dup
1354  // region_dup
1355  // copy_effect
1356  effect init_eff = (*effect_dup_func)(eff);
1357 
1358  /* and then perform the translation */
1360  effect_descriptor(init_eff),
1361  effect_any_reference(real_eff),
1362  effect_descriptor(real_eff),
1363  0,
1364  &n_eff_ref, &n_eff_d,
1365  &exact_translation_p);
1367  {
1368  if (eff_act == is_action_read)
1369  anywhere_r_p = true;
1370  else
1371  anywhere_w_p = true;
1372  }
1373  n_eff = make_effect(make_cell(is_cell_reference, n_eff_ref),
1374  copy_action(effect_action(eff)),
1375  exact_translation_p? copy_approximation(effect_approximation(eff)):
1378  l_eff = gen_nconc(l_eff, CONS(EFFECT, n_eff, NIL));
1379 
1380  free_effect(init_eff);
1381  }
1382  }
1383  }
1384  } /* FOREACH(EFFECT, real_eff, l_real_eff) */
1385  gen_free_list(l_real_arg);
1386  gen_full_free_list(l_real_eff);
1387  } /* if (pointer_type_p(real_arg_t)) */
1388  else
1389  {
1390  pips_debug(8, "real arg reference is not a pointer and is not a partially indexed array -> NIL \n");
1391  } /* else */
1392  break;
1393  }
1394  else if(ENTITY_MALLOC_SYSTEM_P(real_op))
1395  {
1396  /* BC : do not generate effects on HEAP */
1397  /* n_eff = heap_effect(get_current_module_entity(),
1398  * copy_action(effect_action(eff)));*/
1399  }
1400  else
1401  {
1402  l_eff = gen_nconc
1403  (l_eff,
1405  }
1406 
1407  if (n_eff != effect_undefined && l_eff == NIL)
1408  l_eff = CONS(EFFECT,n_eff, NIL);
1409  break;
1410  } /* case is_syntax_call */
1411  case is_syntax_cast :
1412  {
1413  pips_debug(5, "cast case\n");
1414  expression cast_exp = cast_expression(syntax_cast(real_s));
1415  type cast_t = expression_to_type(cast_exp);
1416  /* we should test here the compatibility of the casted expression type with
1417  * the formal entity type. It is not available here, however, I think it's
1418  * equivalent to test the compatibility with the real arg expression type
1419  * since the current function is called after testing the compatilibty between
1420  * the real expression type and the formal parameter type.
1421  */
1423  {
1424  l_eff = gen_nconc
1425  (l_eff,
1427  (l_sum_eff, cast_exp, context));
1428  }
1429  else if (!ENDP(l_sum_eff))
1430  {
1431  /* let us at least generate effects on all memory locations reachable from
1432  * the cast expression
1433  */
1434  cast c = syntax_cast(real_s);
1435  bool read_p = false, write_p = false;
1436  FOREACH(EFFECT, eff, l_sum_eff)
1437  {
1438  if(effect_write_p(eff)) write_p = true;
1439  else read_p = false;
1440  }
1441  tag t = write_p ? (read_p ? 'x' : 'w') : 'r';
1442  l_eff = gen_nconc
1443  (l_eff,
1445  }
1446  break;
1447  }
1449  {
1450  pips_debug(5,"sizeof epxression -> NIL");
1451  break;
1452  }
1453  case is_syntax_va_arg :
1454  {
1455  pips_internal_error("va_arg() : should have been treated before");
1456  break;
1457  }
1458  case is_syntax_application :
1459  {
1460  pips_internal_error("Application not supported yet");
1461  break;
1462  }
1463  case is_syntax_range :
1464  {
1465  pips_user_error("Illegal effective parameter: range\n");
1466  break;
1467  }
1468  default:
1469  pips_internal_error("Illegal kind of syntax");
1470  break;
1471  } /* switch */
1472 
1473  free_type(real_arg_t);
1474  }
1475 
1476  ifdebug(8)
1477  {
1478  pips_debug(8, "end with effects :\n");
1479  print_effects(l_eff);
1480  }
1481 
1482  return(l_eff);
1483 }
1484 
1485 
1486 /* list c_summary_effect_to_proper_effects(effect eff, expression real_arg)
1487  * input : a summary effect eff corresponding to a formal parameter,
1488  * and the corresponding actual argument at the current call site.
1489  * output : a list of new effects in the name space of the caller.
1490  * if the translation is not possible, returns a list of effects
1491  * on the memory locations possibly pointed to by the actual
1492  * argument.
1493  * modifies : nothing.
1494  * comment : Contrarily to the previous version of this function,
1495  * does not modify eff.
1496  * FI: it might be better to return a list of effects including the
1497  * read implied by the evaluation of real_arg
1498  * BC : no because there can be several effects for one real arg. This would
1499  * induce redundant, hence harmful, computations.
1500  *
1501 
1502  */
1504 {
1505  list l_eff = NIL; /* the result */
1506 
1507  reference eff_ref = effect_any_reference(eff);
1508  list eff_ind = reference_indices(eff_ref);
1509 
1510  ifdebug(8)
1511  {
1512  pips_debug(8, "begin for real arg %s, and effect :\n",
1513  expression_to_string(real_arg));
1514  print_effect(eff);
1515  }
1516 
1517  /* Whatever the real_arg may be if there is an effect on the sole value of the
1518  * formal arg, it generates no effect on the caller side.
1519  */
1520 
1521  if (gen_length(eff_ind) == 0)
1522  {
1523  pips_debug(5, "effect on the value of the formal parameter -> NIL\n");
1524  }
1525  else
1526  {
1527  syntax real_s = expression_syntax(real_arg);
1528  type real_arg_t = expression_to_type(real_arg);
1529 
1530  pips_debug(5, "type of real argument expression : %s\n",
1531  type_to_string(real_arg_t));
1532 
1533  switch (syntax_tag(real_s))
1534  {
1535  case is_syntax_reference:
1536  {
1537  reference real_ref = syntax_reference(real_s);
1538  entity real_ent = reference_variable(real_ref);
1539  list real_ind = reference_indices(real_ref);
1540 
1541  /* if it's a pointer or a partially indexed array
1542  * We should do more testing here to check if types
1543  * are compatible... (see effect_array_substitution ?)
1544  */
1545  if (pointer_type_p(real_arg_t) ||
1546  gen_length(real_ind) < type_depth(entity_type(real_ent)))
1547  {
1548  reference eff_ref = effect_any_reference(eff);
1549  list eff_ind = reference_indices(eff_ref);
1550 
1551  reference new_ref = copy_reference(real_ref);
1552  effect new_eff;
1553 
1554  pips_debug(8, "pointer type real arg reference\n");
1555 
1556  /* we add the indices of the effect reference
1557  * to the real reference */
1558  pips_debug(8, "effect on the pointed area : \n");
1559  // functions that can be pointed by reference_to_effect_func:
1560  // reference_to_simple_effect
1561  // reference_to_convex_region
1562  // reference_to_reference_effect
1563  new_eff = (* reference_to_effect_func)(new_ref,
1564  copy_action(effect_action(eff)),false);
1565  FOREACH(EXPRESSION, eff_ind_exp, eff_ind)
1566  {
1567  // functions that can be pointed by effect_add_expression_dimension_func:
1568  // simple_effect_add_expression_dimension
1569  // convex_region_add_expression_dimension
1570  (*effect_add_expression_dimension_func)(new_eff, eff_ind_exp);
1571  }
1572  l_eff = gen_nconc(l_eff, CONS(EFFECT, new_eff, NIL));
1573  } /* if (pointer_type_p(real_arg_t)) */
1574  else
1575  {
1576  pips_debug(8, "real arg reference is not a pointer and is not a partially indexed array -> NIL \n");
1577  } /* else */
1578  break;
1579  } /* case is_syntax_reference */
1580  case is_syntax_subscript:
1581  {
1582  /* I guess this case could be merged with other cases (calls other than adress of, and reference case */
1583  list l_real_arg_eff= NIL;
1584  list l_real_arg = NIL;
1585 
1586  /* first we compute an effect on the real argument */
1588  (real_arg, &l_real_arg_eff, effect_write_p(eff));
1589  gen_full_free_list(l_real_arg);
1590 
1591  FOREACH(EFFECT, real_arg_eff, l_real_arg_eff)
1592  {
1593  if (effect_undefined_p(real_arg_eff))
1594  real_arg_eff =
1596 
1597  if (!anywhere_effect_p(real_arg_eff))
1598  {
1600 
1601  /* then we add the indices of the original_effect */
1602  reference eff_ref = effect_any_reference(eff);
1603  list eff_ind = reference_indices(eff_ref);
1604  FOREACH(EXPRESSION, eff_ind_exp, eff_ind)
1605  {
1606  // functions that can be pointed by effect_add_expression_dimension_func:
1607  // simple_effect_add_expression_dimension
1608  // convex_region_add_expression_dimension
1609  (*effect_add_expression_dimension_func)
1610  (real_arg_eff, eff_ind_exp);
1611  }
1612  }
1613  l_eff = gen_nconc(l_eff, CONS(EFFECT, real_arg_eff, NIL));
1614  }
1615  gen_free_list(l_real_arg_eff);
1616  }
1617  break;
1618  case is_syntax_call:
1619  {
1620  call real_call = syntax_call(real_s);
1621  entity real_op = call_function(real_call);
1622  list args = call_arguments(real_call);
1623  effect n_eff = effect_undefined;
1624 
1625  if (ENTITY_ASSIGN_P(real_op))
1626  {
1628  (eff, EXPRESSION(CAR(CDR(args))));
1629  }
1630  else if(ENTITY_ADDRESS_OF_P(real_op))
1631  {
1632  expression arg1 = EXPRESSION(CAR(args));
1633  list l_real_arg = NIL;
1634  list l_eff1 = NIL;
1635 
1636  /* first we compute an effect on the argument of the
1637  * address_of operator (to treat cases like &(n->m))*/
1638  /* It's very costly because we do not re-use l_real_arg
1639  * We should maybe scan the real args instead of scanning
1640  * the effects : we would do this only once per
1641  * real argument */
1643  (arg1, &l_eff1, effect_write_p(eff));
1644  gen_full_free_list(l_real_arg);
1645 
1646  FOREACH(EFFECT, eff1, l_eff1)
1647  {
1648  if (effect_undefined_p(eff1))
1650  else
1651  {
1652  n_eff = eff1;
1653  effect_approximation(n_eff) =
1655  }
1656  /* BC : This must certainely be improved
1657  * only simple cases are handled .*/
1659  {
1660  expression first_ind = EXPRESSION(CAR(eff_ind));
1661 
1662  /* The operand of & is a scalar expression */
1663  /* the first index of eff reference (which must
1664  * be equal to 0) must not be taken into account.
1665  * The other indices must be appended to n_eff indices
1666  */
1667 
1668  pips_assert("scalar case : the first index of eff must be equal to [0]", expression_equal_integer_p(first_ind, 0));
1669  FOREACH(EXPRESSION, eff_ind_exp, CDR(eff_ind))
1670  {
1671  // functions that can be pointed by effect_add_expression_dimension_func:
1672  // simple_effect_add_expression_dimension
1673  // convex_region_add_expression_dimension
1674  (*effect_add_expression_dimension_func)
1675  (n_eff, eff_ind_exp);
1676  }
1677  }
1678  else
1679  {
1680  expression first_ind = EXPRESSION(CAR(eff_ind));
1681  reference n_eff_ref = effect_any_reference(n_eff);
1682  expression last_n_eff_ind =
1683  EXPRESSION(CAR(gen_last(reference_indices(n_eff_ref))));
1684  expression n_exp;
1685 
1686 
1687  /* The operand of & is subcripted */
1688  /* The first index of eff must be added to the last
1689  * index of n_eff (except if it is unbounded),
1690  * and the remaining indices list
1691  * be appended to th indices of n_eff
1692  * could be more generic
1693  */
1694  if(!unbounded_expression_p(last_n_eff_ind))
1695  {
1696  if(!unbounded_expression_p(first_ind))
1697  {
1698  value v;
1699  n_exp = MakeBinaryCall
1701  last_n_eff_ind, copy_expression(first_ind));
1702  /* Then we must try to evaluate the expression */
1703  v = EvalExpression(n_exp);
1704  if (! value_undefined_p(v) &&
1705  value_constant_p(v))
1706  {
1707  constant vc = value_constant(v);
1708  if (constant_int_p(vc))
1709  {
1710  /* free_expression(n_exp);*/
1711  n_exp = int_to_expression(constant_int(vc));
1712  }
1713  }
1714  }
1715  else
1716  {
1717  n_exp = make_unbounded_expression();
1718  }
1719  CAR(gen_last(reference_indices(n_eff_ref))).p
1720  = (void *) n_exp;
1721  /*should we free last_n_eff_ind ? */
1722  }
1723  FOREACH(EXPRESSION, eff_ind_exp, CDR(eff_ind))
1724  {
1725  // functions that can be pointed by effect_add_expression_dimension_func:
1726  // simple_effect_add_expression_dimension
1727  // convex_region_add_expression_dimension
1728  (*effect_add_expression_dimension_func)
1729  (n_eff, eff_ind_exp);
1730  }
1731  }
1732  l_eff = CONS(EFFECT, n_eff, l_eff);
1733  } /* FOREACH(EFFECT, eff1, l_eff1) */
1734  gen_free_list(l_eff1);
1735  }
1736  else if(ENTITY_POINT_TO_P(real_op)|| ENTITY_FIELD_P(real_op))
1737  {
1738  list l_real_arg = NIL;
1739  list l_eff1 = NIL;
1740  /* first we compute an effect on the real_arg */
1741  /* It's very costly because we do not re-use l_real_arg
1742  * We should maybe scan the real args instead of scanning
1743  * the effects. */
1745  (real_arg, &l_eff1, effect_write_p(eff));
1746  gen_free_list(l_real_arg);
1747 
1748  FOREACH(EFFECT, eff1, l_eff1)
1749  {
1750  if (effect_undefined_p(eff1))
1752  else
1753  {
1754  n_eff = eff1;
1755  effect_approximation(n_eff) =
1757  }
1758 
1759  /* Then we add the indices of the effect reference */
1760  /* Well this is valid only in the general case :
1761  * we should verify that types are compatible.
1762  */
1763  FOREACH(EXPRESSION, ind, eff_ind)
1764  {
1765  // functions that can be pointed by effect_add_expression_dimension_func:
1766  // simple_effect_add_expression_dimension
1767  // convex_region_add_expression_dimension
1768  (*effect_add_expression_dimension_func)(n_eff, ind);
1769  }
1770  l_eff = CONS(EFFECT, n_eff, l_eff);
1771  }
1772  gen_free_list(l_eff1);
1773  }
1774  else if(ENTITY_MALLOC_SYSTEM_P(real_op)) {
1775  /* BC : do not generate effects on HEAP */
1776  /*n_eff = heap_effect(get_current_module_entity(),
1777  copy_action(effect_action(eff)));*/
1778  }
1779  else {
1780  /* We do not know what to do with the initial value */
1782  }
1783 
1784  if (n_eff != effect_undefined && l_eff == NIL)
1785  l_eff = CONS(EFFECT,n_eff, NIL);
1786  break;
1787  } /* case is_syntax_call */
1788  case is_syntax_cast :
1789  {
1790  /* Ignore the cast */
1791  cast c = syntax_cast(real_s);
1792  pips_user_warning("Cast effect is ignored\n");
1794  break;
1795  }
1797  {
1798  pips_debug(5,"sizeof epxression -> NIL");
1799  break;
1800  }
1801  case is_syntax_va_arg :
1802  {
1803  pips_internal_error("va_arg() : should have been treated before");
1804  break;
1805  }
1806  case is_syntax_application :
1807  {
1808  pips_internal_error("Application not supported yet");
1809  break;
1810  }
1811  case is_syntax_range :
1812  {
1813  pips_user_error("Illegal effective parameter: range\n");
1814  break;
1815  }
1816  default:
1817  pips_internal_error("Illegal kind of syntax");
1818  break;
1819  } /* switch */
1820 
1821  free_type(real_arg_t);
1822  } /*else */
1823 
1824  ifdebug(8)
1825  {
1826  pips_debug(8, "end with effects :\n");
1827  print_effects(l_eff);
1828  }
1829 
1830  return(l_eff);
1831 
1832 }
1833 
1834 /* FI: I do not know how deep the copying should be and the
1835  preferences do not help for C because some references are not found
1836  in the program expression but built according to an abstraction. */
1838  entity func,
1839  list /* of expression */ args,
1840  list /* of effect */ func_sdfi)
1841 {
1842  list pel = NIL; /* proper effect list */
1843  list ce = list_undefined; /* current effect */
1844  bool param_varargs_p = false;
1845  type u_func_t = ultimate_type(entity_type(func));
1847 
1848  ifdebug(2)
1849  {
1850  pips_debug(2, "begin for function %s\n", entity_local_name(func));
1851  pips_debug(2, "with actual arguments :\n");
1852  print_expressions(args);
1853  pips_debug(2, "and effects :\n");
1854  print_effects(func_sdfi);
1855  }
1856 
1857  /* first the case of va_args.
1858  * the approach is conservative : we generate may r/w effects
1859  * on all actual arguments. This could and should be refined...
1860  */
1861 
1862  pips_debug(8, "first check for varargs \n");
1863  MAP(PARAMETER, e_param,
1864  {
1865  type te = parameter_type(e_param);
1866  pips_debug(8, "parameter type : %s\n", type_to_string(te));
1867  if(type_varargs_p(te))
1868  {
1869  param_varargs_p = true;
1870  }
1871  },
1872  params);
1873 
1874  if (param_varargs_p)
1875  {
1876  pips_debug(5, "varargs parameters.\n");
1877 
1878  /* First, we keep those effects in the summary list that are not
1879  * effects on formal parameters, that is to say effects on global
1880  * variables.
1881  */
1882 
1883  MAP(EFFECT, eff,
1884  {
1886  entity v = reference_variable(r);
1887 
1888  if(formal_parameter_p(v))
1889  {
1890  pips_debug(8, "effect on formal parameter skipped : %s\n",
1891  entity_name(v));
1892  }
1893  else
1894  {
1895  bool force_may_p = true;
1896 
1897  pips_debug(8, "effect on global entity %s kept.\n",
1898  entity_name(v));
1899 
1900  /* We keep a may effect on the global entity.*/
1901  // functions that can be pointed by effect_to_store_independent_effect_list_func:
1902  // effect_to_store_independent_sdfi_list
1903  // region_to_store_independent_region_list
1904  // functions that can be pointed by effect_dup_func:
1905  // simple_effect_dup
1906  // region_dup
1907  // copy_effect
1908  pel = gen_nconc
1909  (pel,
1911  ((*effect_dup_func)(eff), force_may_p));
1912  }
1913  },
1914  func_sdfi);
1915 
1916  ifdebug(8)
1917  {
1918  pips_debug(8, "effects on global variables :\n");
1919  (* effects_prettyprint_func)(pel);
1920  }
1921 
1922 
1923  /* Then, we add the read effects on actual parameters.
1924  * (I have to check if it is not done by in the callers of this function)
1925  */
1926 
1928  ifdebug(8)
1929  {
1930  pips_debug(8, "effects on actual parameters added :\n");
1931  (* effects_prettyprint_func)(pel);
1932  }
1933 
1934 
1935  /* Lastly, we add the read and write effects on the variables
1936  * pointed by the actual parameters if it makes sense.
1937  */
1938 
1939  pips_debug(5, "Generating r/w effects on variables pointed by actual parameters\n");
1940 
1941  MAP(EXPRESSION, arg,
1942  {
1943  pel = gen_nconc
1945 
1946  }, args);
1947 
1948  } /* if (param_varargs_p) */
1949 
1950  else
1951  {
1952  check_user_call_site(func, args);
1953 
1954  pips_debug(8, "no varargs \n");
1955 
1956  for(ce = func_sdfi; !ENDP(ce); POP(ce))
1957  {
1958  effect eff = EFFECT(CAR(ce));
1960  entity v = reference_variable(r);
1961 
1962  if(formal_parameter_p(v))
1963  {
1964  storage s = entity_storage(v);
1965  formal fs = storage_formal(s);
1966  int rank = formal_offset(fs);
1967  expression ep = EXPRESSION(gen_nth(rank-1, args));
1968  list l_sum = NIL;
1969 
1970  l_sum = c_summary_effect_to_proper_effects(eff, ep);
1971  pel = gen_nconc(pel,l_sum);
1972 
1973  /* FI: I'm not too sure about this...
1974  * BC : It should be done later, because there can be several
1975  * effects for one real arg entity.So it generates redundant
1976  * effects that will need costly unioning.
1977  */
1979 
1980  } /* if(formal_parameter_p(v)) */
1981  else
1982  {
1983  /* This effect must be a global effect. It does not require
1984  * translation in C. However, it may not be in the scope of the caller. */
1985  // functions that can be pointed by effect_dup_func:
1986  // simple_effect_dup
1987  // region_dup
1988  // copy_effect
1989  pel = gen_nconc(pel, CONS(EFFECT, (*effect_dup_func)(eff), NIL));
1990  } /* else */
1991  } /* for */
1992  } /* else */
1993 
1994  ifdebug(5)
1995  {
1996  pips_debug(5, "resulting effects :\n");
1997  (*effects_prettyprint_func)(pel);
1998  }
1999  return pel;
2000 }
2001 
2002 list /* of effect */
2004  entity func,
2005  list /* of expression */ args,
2006  list /* of effect */ func_sdfi)
2007 {
2008  list el = list_undefined;
2010  el = fortran_summary_to_proper_effects(func, args, func_sdfi);
2011  else
2012  el = c_summary_to_proper_effects(func, args, func_sdfi);
2013 
2014  return el;
2015 }
2016 
2017 /****************************************************** FORWARD TRANSLATION */
2018 
2019 #define make_translated_effect(entity,action,approximation)\
2020  make_effect(make_cell(is_cell_reference, make_reference((entity), NIL)),\
2021  copy_action(action),\
2022  make_approximation(approximation, UU),\
2023  make_descriptor_none())
2024 
2025 /* I'm responsible for this piece of code for out simple effects.
2026  * I have been inspired by the corresponding function in convex effects.
2027  *
2028  * FC. August 1997.
2029  */
2030 
2031 /* actual/formal arguments forward translation:
2032  *
2033  * CALL FOO(A(*)), SUBROUTINE FOO(B(*)): effect on A => effect on B
2034  */
2035 static list /* of effect */
2036 real_simple_effects_forward_translation(
2037  entity func,
2038  list /* of expression */ real_args,
2039  list /* of effect */ l_eff)
2040 {
2041  list /* of effect */ l_fwd_translated = NIL; /* what is being built */
2042  int arg_num = 1;
2043 
2044  MAP(EXPRESSION, e,
2045  {
2046  if (expression_reference_p(e))
2047  {
2048  /* something to translate */
2050  entity form = find_ith_formal_parameter(func, arg_num);
2051 
2052  pips_assert("ith formal is defined", !entity_undefined_p(form));
2053 
2054  /* look for an effect on actu or equivalenced
2055  */
2056  MAP(EFFECT, ef,
2057  {
2058  /* ??? should be "may interfere" */
2059  if (same_entity_p(effect_variable(ef),actu))
2060  {
2061  /* approximation:
2062  * Actual is array => MAY(formal);
2063  * Actual is scalar => actual(formal);
2064  */
2065  tag approx = entity_scalar_p(actu)?
2068 
2069  effect fef = make_translated_effect
2070  (form, effect_action(ef), approx);
2071 
2072  /* better union not needed, all different ??? bof. */
2073  l_fwd_translated = CONS(EFFECT, fef, l_fwd_translated);
2074  }
2075  },
2076  l_eff);
2077  }
2078  /* else could checks sg */
2079 
2080  arg_num++;
2081  },
2082  real_args);
2083 
2084  return l_fwd_translated;
2085 }
2086 
2087 /* translation of global effects (i.e. variables in commons.
2088  */
2089 static list /* of effect */
2090 common_simple_effects_forward_translation(
2091  entity callee,
2092  list /* of effect */ l_eff)
2093 {
2094  list l_fwd_translated = NIL;
2095 
2096  MAP(EFFECT, e,
2097  {
2098  entity a = effect_variable(e);
2099  storage s = entity_storage(a);
2103  {
2104  pips_debug(5, "considering common variable %s\n", entity_name(a));
2105 
2106  /* some better union??? */
2107  l_fwd_translated = gen_nconc(
2108  global_effect_translation
2109  (e, get_current_module_entity(), callee), l_fwd_translated);
2110  }
2111  },
2112  l_eff);
2113 
2114  return l_fwd_translated;
2115 }
2116 
2117 /* OUT effects are translated forward to a call.
2118  */
2119 list /* of effect */
2121  entity callee,
2122  list /* of expression */ real_args,
2123  list /* of effect */ l_eff,
2124  transformer context __attribute__ ((unused)))
2125 {
2126  list /* of effect */ lr, lc;
2127 
2128  pips_debug(4, "forward translation of %s call to %s\n",
2130  entity_name(callee));
2131 
2132  lr = real_simple_effects_forward_translation(callee, real_args, l_eff);
2133  lc = common_simple_effects_forward_translation(callee, l_eff);
2134 
2135  return gen_nconc(lr, lc);
2136 }
2137 
2138 list
2140  expression real_exp,
2141  entity formal_ent,
2142  list l_eff,
2143  transformer __attribute__ ((unused)) context)
2144 {
2145  syntax real_s = expression_syntax(real_exp);
2146  list l_formal = NIL;
2147 
2148  pips_debug_effects(6,"initial effects :\n", l_eff);
2149 
2150 
2151  switch (syntax_tag(real_s))
2152  {
2153  case is_syntax_call:
2154  {
2155  call real_call = syntax_call(real_s);
2156  entity real_op = call_function(real_call);
2157  list args = call_arguments(real_call);
2158  type uet = ultimate_type(entity_type(real_op));
2159  value real_op_v = entity_initial(real_op);
2160 
2161  pips_debug(5, "call case, function %s \n", module_local_name(real_op));
2162  if(type_functional_p(uet))
2163  {
2164  if (value_code_p(real_op_v))
2165  {
2166  pips_debug(5, "external function\n");
2167  pips_user_warning("Nested function calls are ignored. Consider splitting the code before running PIPS\n");
2168  l_formal = NIL;
2169  break;
2170  }
2171  else /* it's an intrinsic */
2172  {
2173  pips_debug(5, "intrinsic function\n");
2174 
2175  if (ENTITY_ASSIGN_P(real_op))
2176  {
2177  pips_debug(5, "assignment case\n");
2179  (callee, EXPRESSION(CAR(CDR(args))), formal_ent, l_eff, context);
2180  break;
2181  }
2182  else if(ENTITY_ADDRESS_OF_P(real_op))
2183  {
2184  expression arg1 = EXPRESSION(CAR(args));
2185  list l_real_arg = NIL;
2186  bool general_case = true;
2187 
2188  pips_debug(5, "address of case\n");
2189 
2190  /* first we compute an effect on the argument of the address_of operator.
2191  * This is to distinguish between the general case and the case where
2192  * the operand of the & operator is an array element.
2193  */
2194  list l_eff_real = NIL;
2196  (arg1, &l_eff_real, true);
2197  gen_full_free_list(l_real_arg);
2198 
2199  effect eff_real = EFFECT(CAR(l_eff_real)); /* there should be a FOREACH here to scan the whole list */
2200  gen_free_list(l_eff_real);
2201 
2202  reference eff_real_ref = effect_any_reference(eff_real);
2203  list l_inds_real = reference_indices(eff_real_ref);
2204  int nb_phi_real = (int) gen_length(l_inds_real);
2205 
2206 
2207  /* there are indices but we don't know if they represent array dimensions,
2208  * struct/union/enum fields, or pointer dimensions.
2209  */
2210  if(nb_phi_real > 0)
2211  {
2212  type t = type_undefined;
2213 
2214  t = simple_effect_reference_type(eff_real_ref);
2215 
2216  if (type_undefined_p(t))
2217  pips_internal_error("undefined type not expected ");
2218 
2220  {
2221  pips_debug(5,"array element or sub-array case\n");
2222  /* array element operand : we replace the last index with
2223  * an unbounded dimension */
2226  nb_phi_real);
2227  general_case = false;
2228  }
2229  else
2230  pips_debug(5, "general case\n");
2231  }
2232 
2233 
2234  FOREACH(EFFECT, eff_orig, l_eff)
2235  {
2236  list l_inds_orig = reference_indices(effect_any_reference(eff_orig));
2237 
2238  /* First we have to test if the eff_real access path leads to the eff_orig access path */
2239 
2240  /* to do that, if the entities are the same (well in fact we should also
2241  * take care of aliasing), we add the constraints of eff_real to those of eff_orig,
2242  * and the system must be feasible.
2243  * We should also take care of linearization here.
2244  */
2245  bool exact_p;
2246  if(path_preceding_p(eff_real, eff_orig, transformer_undefined, false, &exact_p))
2247  {
2248  /* At least part of the original effect corresponds to the actual argument :
2249  * we need to translate it
2250  */
2251  pips_debug_effect(5, "matching access paths, considered effect is : \n", eff_orig);
2252 
2253  /* Then we skip the dimensions common to the two regions
2254  * except the last one if we are not in the general case */
2255  /* This is only valid when there is no linearization.
2256  */
2257  int i_max = general_case? nb_phi_real : nb_phi_real-1;
2258  for(int i = 1; i<= i_max; i++, POP(l_inds_orig));
2259  list l_new_inds = gen_full_copy_list(l_inds_orig);
2260 
2261  /* Then, we must add a first dimension with index 0 constraint
2262  * in the general case.
2263  * We must also change the resulting effect
2264  * entity for the formal entity in all cases.
2265  */
2266 
2267  if (general_case)
2268  l_new_inds = CONS(EXPRESSION, int_to_expression(0), l_new_inds);
2269 
2270  effect eff_formal = make_reference_simple_effect(make_reference(formal_ent,l_new_inds),
2271  copy_action(effect_action(eff_orig)),
2272  exact_p? copy_approximation(effect_approximation(eff_orig))
2274 
2275  pips_debug_effect(5, "resulting eff_formal\n", eff_formal);
2276 
2277  l_formal = EffectsMustUnion(l_formal, CONS(EFFECT, eff_formal, NIL),
2279  pips_debug_effects(6,"l_formal after adding new effect : \n", l_formal);
2280 
2281 
2282  } /* if(path_preceding_p...)*/
2283 
2284  } /* FOREACH */
2285 
2286  break;
2287  }
2288  else
2289  {
2290  pips_debug(5, "Other intrinsic case : entering general case \n");
2291  }
2292  }
2293  }
2294  else if(type_variable_p(uet))
2295  {
2296  pips_user_warning("Effects of call thru functional pointers are ignored\n");
2297  l_formal = NIL;
2298  break;
2299  }
2300  }
2301  // entering general case which includes general calls
2302  _FALLTHROUGH_;
2303  case is_syntax_reference:
2304  case is_syntax_subscript:
2305  {
2306  effect eff_real = effect_undefined;
2307 
2308  pips_debug(5, "general case\n");
2309 
2310  /* first we compute an effect on the real_arg */
2311  if (syntax_reference_p(real_s))
2313  else
2314  {
2315  list l_eff_real = NIL;
2317  (real_exp, &l_eff_real, true);
2318  gen_full_free_list(l_real_arg);
2319  if (!ENDP(l_eff_real))
2320  eff_real = EFFECT(CAR(l_eff_real)); /*there should be a foreach to scan all the elements */
2321  gen_free_list(l_eff_real);
2322  }
2323 
2324  if (!effect_undefined_p(eff_real))
2325  {
2326  FOREACH(EFFECT, eff_orig, l_eff)
2327  {
2328  int nb_phi_orig = (int) gen_length(reference_indices(effect_any_reference(eff_orig)));
2329  int nb_phi_real = (int) gen_length(reference_indices(effect_any_reference(eff_real)));
2330  /* First we have to test if the eff_real access path leads to the eff_orig access path */
2331 
2332  bool exact_p;
2333  if(path_preceding_p(eff_real, eff_orig, transformer_undefined, true, &exact_p)
2334  && nb_phi_orig >= nb_phi_real)
2335  {
2336  /* At least part of the original effect corresponds to the actual argument :
2337  * we need to translate it
2338  */
2339  reference ref_formal = make_reference(formal_ent, NIL);
2340  effect eff_formal = reference_to_simple_effect(ref_formal, copy_action(effect_action(eff_orig)),
2341  false);
2342 
2343  pips_debug_effect(5, "matching access paths, considered effect is : \n", eff_orig);
2344 
2345  /* first we perform the path translation */
2346  reference n_eff_ref;
2347  descriptor n_eff_d;
2348  effect n_eff;
2349  bool exact_translation_p;
2351  effect_descriptor(eff_orig),
2352  ref_formal,
2353  effect_descriptor(eff_formal),
2354  nb_phi_real,
2355  &n_eff_ref, &n_eff_d,
2356  &exact_translation_p);
2357  n_eff = make_reference_simple_effect(n_eff_ref, copy_action(effect_action(eff_orig)),
2358  exact_translation_p? copy_approximation(effect_approximation(eff_orig)) : make_approximation_may());
2359  pips_debug_effect(5, "final eff_formal : \n", n_eff);
2360 
2361  pips_debug_effect(5, "eff_formal after context translation: \n", n_eff);
2362 
2363  l_formal = EffectsMustUnion(l_formal, CONS(EFFECT, n_eff, NIL),effects_same_action_p);
2364  pips_debug_effects(6, "l_formal after adding new effect : \n", l_formal);
2365 
2366  } /* if(effect_entity(eff_orig) == effect_entity(eff_real) ...)*/
2367 
2368 
2369 
2370  /* */
2371 
2372  } /* FOREACH */
2373  }
2374 
2375  break;
2376  }
2377  case is_syntax_application:
2378  {
2379  pips_internal_error("Application not supported yet");
2380  break;
2381  }
2382 
2383  case is_syntax_cast:
2384  {
2385  pips_debug(6, "cast expression\n");
2386  type formal_ent_type = entity_basic_concrete_type(formal_ent);
2387  expression cast_exp = cast_expression(syntax_cast(real_s));
2388  type cast_exp_type = expression_to_type(cast_exp);
2390  {
2391  l_formal =
2393  (callee, cast_exp,
2394  formal_ent, l_eff, context);
2395  }
2396  else
2397  {
2398  expression formal_exp = entity_to_expression(formal_ent);
2399  l_formal = c_actual_argument_to_may_summary_effects(formal_exp, 'w');
2400  free_expression(formal_exp);
2401  }
2402  free_type(cast_exp_type);
2403  break;
2404  }
2405  case is_syntax_range:
2406  {
2407  pips_user_error("Illegal effective parameter: range\n");
2408  break;
2409  }
2410 
2412  {
2413  pips_debug(6, "sizeofexpression : -> NIL");
2414  l_formal = NIL;
2415  break;
2416  }
2417  case is_syntax_va_arg:
2418  {
2419  pips_internal_error("va_arg not supported yet");
2420  break;
2421  }
2422  default:
2423  pips_internal_error("Illegal kind of syntax");
2424 
2425  } /* switch */
2426 
2427  pips_debug_effects(6,"resulting effects :\n", l_formal);
2428  return(l_formal);
2429 }
float a2sf[2] __attribute__((aligned(16)))
USER generates a user error (i.e., non fatal) by printing the given MSG according to the FMT.
Definition: 3dnow.h:3
action copy_action(action p)
ACTION.
Definition: effects.c:77
descriptor make_descriptor(enum descriptor_utype tag, void *val)
Definition: effects.c:433
void free_effect(effect p)
Definition: effects.c:451
cell make_cell(enum cell_utype tag, void *val)
Definition: effects.c:290
approximation make_approximation(enum approximation_utype tag, void *val)
Definition: effects.c:176
approximation copy_approximation(approximation p)
APPROXIMATION.
Definition: effects.c:132
approximation make_approximation_may(void)
Definition: effects.c:179
effect make_effect(cell a1, action a2, approximation a3, descriptor a4)
Definition: effects.c:484
descriptor copy_descriptor(descriptor p)
DESCRIPTOR.
Definition: effects.c:389
cell make_cell_preference(preference _field_)
Definition: effects.c:296
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
void free_expression(expression p)
Definition: ri.c:853
reference copy_reference(reference p)
REFERENCE.
Definition: ri.c:2047
void free_type(type p)
Definition: ri.c:2658
preference make_preference(reference a1)
Definition: ri.c:1862
struct paramStruct params
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
void dump_arguments(cons *args)
entity_name is a macro, hence the code replication
Definition: arguments.c:69
void const char const char const int
#define VALUE_MONE
#define VALUE_ONE
#define CONTRAINTE_UNDEFINED
Pcontrainte contrainte_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
#define min(a, b)
#define max(a, b)
static Value offset
Definition: translation.c:283
#define pips_debug_effects(level, message, l_eff)
#define pips_debug_effect(level, message, eff)
for debug
list generic_proper_effects_of_complex_address_expression(expression, list *, int)
effect make_anywhere_effect(action)
string vect_debug_entity_name(entity)
list(* effect_to_store_independent_effect_list_func)(effect, bool)
type simple_effect_reference_type(reference)
list generic_proper_effects_of_expression(expression)
effect(* effect_dup_func)(effect eff)
list c_actual_argument_to_may_summary_effects(expression, tag)
list effect_to_list(effect)
list generic_effect_generate_all_accessible_paths_effects(effect, type, tag)
bool effects_same_action_p(effect, effect)
list generic_proper_effects_of_expressions(list)
#define make_sdfi_effect(e)
copies an effect with no subcript expression
list EffectsMustUnion(list l1, list l2, bool(*union_combinable_p)(effect, effect))
list EffectsMustUnion(list l1, list l2, union_combinable_p) input : two lists of effects output : a l...
bool path_preceding_p(effect, effect, transformer, bool, bool *)
Definition: eval.c:132
void simple_effect_descriptor_interprocedural_translation(effect)
void simple_cell_reference_with_address_of_cell_reference_translation(reference, descriptor, reference, descriptor, int, reference *, descriptor *, bool *)
list c_simple_effects_on_formal_parameter_backward_translation(list, expression, transformer)
void simple_effect_change_ith_dimension_expression(effect, expression, int)
list effect_to_sdfi_list(effect)
list effects_dynamic_elim(list)
void simple_effects_translation_init(entity, list, bool)
interprocedural.c
list fortran_summary_to_proper_effects(entity, list, list)
list c_simple_effects_on_actual_parameter_forward_translation(entity, expression, entity, list, transformer)
effect translate_effect_to_sdfi_effect(effect)
effect reference_to_simple_effect(reference, action, bool)
unary_operators.c
list summary_to_proper_effects(entity, list, list)
list simple_effects_backward_translation(entity, list, list, transformer)
list summary_effect_to_proper_effect(call, effect)
string effect_to_string(effect)
void check_user_call_site(entity, list)
void simple_cell_reference_with_value_of_cell_reference_translation(reference, descriptor, reference, descriptor, int, reference *, descriptor *, bool *)
list words_effect(effect)
list c_summary_effect_to_proper_effects(effect, expression)
list make_unknown_subscript(int)
list c_summary_to_proper_effects(entity, list, list)
list simple_effects_forward_translation(entity, list, list, transformer)
void simple_effects_translation_end(void)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define effect_approximation_tag(eff)
#define make_reference_simple_effect(reference, action, approximation)
#define effect_write_p(eff)
#define effect_read_p(eff)
#define effect_scalar_p(eff) entity_scalar_p(effect_entity(eff))
#define effect_exact_p(eff)
#define effect_variable(e)
For COMPATIBILITY purpose only - DO NOT USE anymore.
#define effect_action_tag(eff)
#define make_simple_effect(reference, action, approximation)
bool basic_concrete_types_compatible_for_effects_interprocedural_translation_p(type, type)
tests if the actual argument type and the formal argument type are compatible with the current state ...
Definition: type.c:699
entity effect_entity(effect)
cproto-generated files
Definition: effects.c:52
action make_action_write_memory(void)
To ease the extension of action with action_kind.
Definition: effects.c:1011
bool store_effect_p(effect)
Definition: effects.c:1062
bool anywhere_effect_p(effect)
Is it an anywhere effect? ANYMMODULE:ANYWHERE
Definition: effects.c:346
action make_action_read_memory(void)
Definition: effects.c:1017
bool types_compatible_for_effects_interprocedural_translation_p(type, type)
tests if the actual argument type and the formal argument type are compatible with the current state ...
Definition: type.c:932
bool any_anywhere_effect_p(effect)
Is it a typed or untyped anywhere effect?
Definition: effects.c:358
#define effect_undefined_p(x)
Definition: effects.h:615
#define approximation_tag(x)
Definition: effects.h:362
#define effect_action(x)
Definition: effects.h:642
#define effect_undefined
Definition: effects.h:614
#define action_write_p(x)
Definition: effects.h:314
@ is_cell_reference
Definition: effects.h:445
#define action_read_p(x)
Definition: effects.h:311
@ is_descriptor_none
Definition: effects.h:576
#define effect_descriptor(x)
Definition: effects.h:646
#define descriptor_undefined
Definition: effects.h:559
@ is_action_write
Definition: effects.h:293
@ is_action_read
Definition: effects.h:292
@ is_approximation_may
Definition: effects.h:341
#define effect_approximation(x)
Definition: effects.h:644
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
void gen_full_free_list(list l)
Definition: genClib.c:1023
static int array_size(dim)
ARRAY_SIZE returns the number of elements in the array whose dimension list is DIM.
Definition: genClib.c:155
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
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
#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
gen_chunk gen_nth(int n, const list l)
to be used as ENTITY(gen_nth(3, l))...
Definition: list.c:710
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
list gen_full_copy_list(list l)
Copy a list structure with element copy.
Definition: list.c:535
static list indices
Definition: icm.c:204
static void term(Pproblem XX, int s, Value k, int x)
Definition: isolve.c:315
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 pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_user_warning
Definition: misc-local.h:146
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_internal_error
Definition: misc-local.h:149
#define user_warning(fn,...)
Definition: misc-local.h:262
#define _FALLTHROUGH_
Definition: misc-local.h:238
#define pips_user_error
Definition: misc-local.h:147
int get_debug_level(void)
GET_DEBUG_LEVEL returns the current debugging level.
Definition: debug.c:67
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
static entity rank
string bool_to_string(bool)
Definition: string.c:243
int tag
TAG.
Definition: newgen_types.h:92
#define UU
Definition: newgen_types.h:98
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
void print_expressions(list le)
Definition: expression.c:98
string expression_to_string(expression e)
Definition: expression.c:77
#define print_effect(e)
Definition: print.c:336
#define print_effects(e)
Definition: print.c:334
#define SUBSTRING_FUNCTION_NAME
#define ENTITY_ASSIGN_P(e)
#define ENTITY_DEREFERENCING_P(e)
#define PLUS_OPERATOR_NAME
#define NORMALIZE_EXPRESSION(e)
#define ENTITY_POINT_TO_P(e)
#define ENTITY_FIELD_P(e)
C data structure and pointer management.
#define ENTITY_MALLOC_SYSTEM_P(e)
#define ENTITY_ADDRESS_OF_P(e)
bool dynamic_area_p(entity aire)
Definition: area.c:68
bool stack_area_p(entity aire)
Definition: area.c:104
bool heap_area_p(entity aire)
Definition: area.c:86
bool entity_special_area_p(entity e)
Definition: area.c:154
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
bool intrinsic_entity_p(entity e)
Definition: entity.c:1272
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
bool c_module_p(entity m)
Test if a module "m" is written in C.
Definition: entity.c:2777
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
bool effects_package_entity_p(entity e)
checks if an entity is an IO_EFFECTS_PACKAGE_NAME, a MALLOC_EFFECTS_NAME or a RAND_EFFECTS_PACKAGE_NA...
Definition: entity.c:1181
expression entity_ith_bounds(entity e, int i)
FIND_MODULE returns entity.
Definition: entity.c:1626
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
bool parameter_passing_by_reference_p(entity f)
Definition: entity.c:2121
bool top_level_entity_p(entity e)
Check if the scope of entity e is global.
Definition: entity.c:1130
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
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
Pvecteur vect_product(Pvecteur *pv1, Pvecteur *pv2)
returns a Pvecteur equal to (*pv1) * (*pv2) if this product is linear or NULL otherwise.
Definition: eval.c:1032
value EvalExpression(expression e)
Evaluate statically an expression.
Definition: eval.c:108
bool reference_with_unbounded_indices_p(reference r)
indices can be constant or unbounded: they are store independent.
Definition: expression.c:3066
list make_unbounded_subscripts(int d)
FI: this piece of code must have been duplicated somewhere else in an effect library.
Definition: expression.c:4346
expression make_unbounded_expression()
Definition: expression.c:4339
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
bool expression_equal_integer_p(expression exp, int i)
================================================================
Definition: expression.c:1977
bool unbounded_expression_p(expression e)
Definition: expression.c:4329
bool reference_with_constant_indices_p(reference r)
Definition: expression.c:3022
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
list module_formal_parameters(entity func)
list module_formal_parameters(entity func) input : an entity representing a function.
Definition: module.c:327
dimension entity_ith_dimension(entity, int)
Another semantics would be: is this reference r to e a kill for e? In general, this cannot be answere...
Definition: variable.c:1228
type ultimate_type(type)
Definition: type.c:3466
type expression_to_type(expression)
For an array declared as int a[10][20], the type returned for a[i] is int [20].
Definition: type.c:2486
bool 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 pointer_type_p(type)
Check for scalar pointers.
Definition: type.c:2993
size_t type_depth(type)
Number of steps to access the lowest leave of type t without dereferencing.
Definition: type.c:4880
bool formal_parameter_p(entity)
Definition: variable.c:1489
int NumberOfDimension(entity)
Definition: size.c:588
bool ith_parameter_p(entity, entity, int)
returns true if v is the ith formal parameter of function f
Definition: util.c:125
type reference_to_type(reference)
Definition: type.c:2354
bool self_initialization_p(entity)
Check if a variable is initialized by itself as "int a = a;" is legal C code according to gcc.
Definition: variable.c:1966
bool entity_integer_scalar_p(entity)
for variables (like I), not constants (like 1)! use integer_constant_p() for constants
Definition: variable.c:1130
entity find_ith_parameter(entity, int)
Definition: util.c:93
string type_to_string(const type)
type.c
Definition: type.c:51
#define type_functional_p(x)
Definition: ri.h:2950
#define formal_offset(x)
Definition: ri.h:1408
#define value_undefined_p(x)
Definition: ri.h:3017
#define value_code_p(x)
Definition: ri.h:3065
#define syntax_reference_p(x)
Definition: ri.h:2728
#define transformer_undefined
Definition: ri.h:2847
#define storage_formal_p(x)
Definition: ri.h:2522
#define parameter_type(x)
Definition: ri.h:1819
#define value_constant(x)
Definition: ri.h:3073
#define syntax_reference(x)
Definition: ri.h:2730
#define syntax_tag(x)
Definition: ri.h:2727
#define normalized_linear_p(x)
Definition: ri.h:1779
#define call_function(x)
Definition: ri.h:709
#define reference_variable(x)
Definition: ri.h:2326
#define storage_tag(x)
Definition: ri.h:2515
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define constant_int(x)
Definition: ri.h:850
#define syntax_call_p(x)
Definition: ri.h:2734
#define syntax_cast(x)
Definition: ri.h:2739
#define type_functional(x)
Definition: ri.h:2952
#define dimension_lower(x)
Definition: ri.h:980
#define type_variable(x)
Definition: ri.h:2949
#define entity_storage(x)
Definition: ri.h:2794
@ is_syntax_range
Definition: ri.h:2692
@ is_syntax_application
Definition: ri.h:2697
@ is_syntax_cast
Definition: ri.h:2694
@ is_syntax_call
Definition: ri.h:2693
@ is_syntax_va_arg
Definition: ri.h:2698
@ is_syntax_reference
Definition: ri.h:2691
@ is_syntax_sizeofexpression
Definition: ri.h:2695
@ is_syntax_subscript
Definition: ri.h:2696
#define storage_ram_p(x)
Definition: ri.h:2519
#define value_constant_p(x)
Definition: ri.h:3071
#define ram_section(x)
Definition: ri.h:2249
#define storage_formal(x)
Definition: ri.h:2524
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define cast_expression(x)
Definition: ri.h:747
@ is_storage_rom
Definition: ri.h:2494
@ is_storage_return
Definition: ri.h:2491
@ is_storage_ram
Definition: ri.h:2492
@ is_storage_formal
Definition: ri.h:2493
#define type_undefined_p(x)
Definition: ri.h:2884
#define entity_undefined_p(x)
Definition: ri.h:2762
#define constant_int_p(x)
Definition: ri.h:848
#define entity_name(x)
Definition: ri.h:2790
#define area_layout(x)
Definition: ri.h:546
#define functional_parameters(x)
Definition: ri.h:1442
#define PARAMETER(x)
PARAMETER.
Definition: ri.h:1788
#define dimension_upper(x)
Definition: ri.h:982
#define reference_indices(x)
Definition: ri.h:2328
#define syntax_call(x)
Definition: ri.h:2736
#define type_area(x)
Definition: ri.h:2946
#define type_varargs_p(x)
Definition: ri.h:2953
#define variable_dimensions(x)
Definition: ri.h:3122
#define storage_ram(x)
Definition: ri.h:2521
#define type_undefined
Definition: ri.h:2883
#define call_arguments(x)
Definition: ri.h:711
#define entity_type(x)
Definition: ri.h:2792
#define value_expression_p(x)
Definition: ri.h:3080
#define normalized_linear(x)
Definition: ri.h:1781
#define expression_syntax(x)
Definition: ri.h:1247
#define type_variable_p(x)
Definition: ri.h:2947
#define value_expression(x)
Definition: ri.h:3082
#define ram_offset(x)
Definition: ri.h:2251
#define entity_initial(x)
Definition: ri.h:2796
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
bool sc_empty_p(Psysteme sc)
bool sc_empty_p(Psysteme sc): check if the set associated to sc is the constant sc_empty or not.
Definition: sc_alloc.c:350
void sc_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
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
Psysteme sc_normalize(Psysteme ps)
Psysteme sc_normalize(Psysteme ps): normalisation d'un systeme d'equation et d'inequations lineaires ...
#define ifdebug(n)
Definition: sg.c:47
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
Definition: delay.c:253
string words_to_string(cons *lw)
Definition: print.c:211
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
char *(* get_variable_name_t)(Variable)
Definition: vecteur-local.h:62
struct Svecteur * Pvecteur
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
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_add(Pvecteur v1, Pvecteur v2)
package vecteur - operations binaires
Definition: binaires.c:53
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(Pvecteur v, Value lambda, Pvecteur u)
Definition: binaires.c:181
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