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 regions : Alexis Platonoff, 22 Aout 1990, Be'atrice Creusillet 10/94
28  *
29  * interprocedural
30  * ---------------
31  *
32  * This File contains the main functions that compute the interprocedural
33  * translation of regions (forward and backward).
34  *
35  * Vocabulary : _ A variable refered as a "region" is in fact of the NEWGEN
36  * type "effect". The use of the word "region" allows to keep
37  * the difference with the effects package.
38  * _ The word "func" always refers to the external called
39  * subroutine.
40  * _ The word "real" always refers to the calling subroutine
41  */
42 
43 #include <stdio.h>
44 #include <string.h>
45 
46 #include <setjmp.h>
47 
48 #include "genC.h"
49 #include "linear.h"
50 #include "ri.h"
51 #include "effects.h"
52 #include "database.h"
53 
54 #include "ri-util.h"
55 #include "prettyprint.h"
56 #include "effects-util.h"
57 #include "constants.h"
58 #include "misc.h"
59 #include "semantics.h"
60 #include "text.h"
61 #include "text-util.h"
62 
63 #include "sommet.h"
64 #include "ray_dte.h"
65 #include "sg.h"
66 
67 #include "sc.h"
68 #include "polyedre.h"
69 
70 #include "transformer.h"
71 
72 #include "pipsdbm.h"
73 #include "resources.h"
74 
75 #include "effects-generic.h"
76 #include "effects-convex.h"
77 #include "effects-simple.h"
78 
79 #define IS_EG true
80 #define NOT_EG false
81 
82 #define PHI_FIRST true
83 #define NOT_PHI_FIRST false
84 
85 #define BACKWARD true
86 #define FORWARD false
87 
88 #define min(a,b) (((a)<(b))?(a):(b))
89 #define max(a,b) (((a)>(b))?(a):(b))
90 
91 
92 
93 /* jmp_buf overflow_error;*/
94 
95 
96 /*********************************************************** INITIALIZATION */
97 
98 void convex_regions_translation_init(entity callee, list real_args, bool backward_p )
99 {
100 
102  if (backward_p)
104  else
106 }
107 
109 {
112 }
113 
114 
115 /************************************************************** INTERFACES */
116 
120 
122 {
124 }
125 
127 {
129  l_sum_out_reg = l_out;
130  else
133 }
134 
136 {
137  return(l_sum_out_reg);
138 }
139 
140 static bool stmt_filter(s)
141 statement s;
142 {
143  pips_debug(1, "statement %td\n", statement_number(s));
144 
145  current_stmt = s;
146  return(true);
147 }
148 
149 
151 {
152  const char *caller_name;
153  statement caller_statement;
154 
157  caller_name = module_local_name(caller);
158  pips_debug(2, "begin for caller: %s\n", caller_name);
159 
160  /* All we need to perform the translation */
162  db_get_memory_resource(DBR_CODE, caller_name, true) );
164  db_get_memory_resource(DBR_CUMULATED_EFFECTS, caller_name, true));
166  db_get_memory_resource(DBR_PROPER_EFFECTS, caller_name, true));
167  module_to_value_mappings(caller);
169  db_get_memory_resource(DBR_PRECONDITIONS, caller_name, true));
170 
172  db_get_memory_resource(DBR_OUT_REGIONS, caller_name, true) );
173 
174  caller_statement = (statement)
175  db_get_memory_resource (DBR_CODE, caller_name, true);
176 
178  gen_multi_recurse(caller_statement,
181  NULL);
182 
185 
187 
193  //free_value_mappings();
194  pips_debug(2, "end\n");
195  return(l_sum_out_reg);
196 }
197 
198 /* void out_regions_from_call_site_to_callee(call c)
199  * input : a potential call site for current_callee.
200  * output : nothing
201  * modifies : l_sum_out_reg becomes the may union of l_sum_out_reg and
202  * the translated out regions of the current call site.
203  * comment :
204  */
206 {
208  list l_out = NIL, l_tmp = NIL;
209 
210  if (call_function(c) != current_callee)
211  return;
212 
215 
217  context);
219 }
220 
221 
222 /* list in_regions_of_external(entity func, list real_args, transformer context)
223  * input : an external function func, and the list of real arguments used
224  * in the calling function.
225  * output : the corresponding list of regions, at call site.
226  * modifies : nothing.
227  * comment : The effects of "func" are computed into externals effects,
228  * ie. `translated'. The translation is made in two phases :
229  * _ regions on formal parameters
230  * _ regions on common parameters
231  */
233 entity func;
234 list real_args;
236 {
237  list le = NIL;
238  const char *func_name = module_local_name(func);
239 
240  pips_debug(4, "translation regions for %s\n", func_name);
241 
242  if (! entity_module_p(func))
243  {
244  pips_internal_error("%s: bad function", func_name);
245  }
246  else
247  {
248  list func_regions;
249 
250  /* Get the regions of "func". */
251  func_regions = effects_to_list((effects)
252  db_get_memory_resource(DBR_IN_SUMMARY_REGIONS, func_name, true));
253  /* translate them */
254  le = regions_backward_translation(func, real_args, func_regions, context,
255  SUMMARY);
256  }
257  return le;
258 }
259 
260 
261 /* list regions_of_external(entity func, list real_args, transformer context)
262  * input : an external function func, and the list of real arguments used
263  * in the calling function.
264  * output : the corresponding list of regions, at call site.
265  * modifies : nothing.
266  * comment : The effects of "func" are computed into externals effects,
267  * ie. `translated'. The translation is made in two phases :
268  * _ regions on formal parameters
269  * _ regions on common parameters
270  */
272  bool proper)
273 {
274  list le = NIL;
275  const char *func_name = module_local_name(func);
276 
277  pips_debug(4, "translation regions for %s\n", func_name);
278 
279  if (! entity_module_p(func))
280  {
281  pips_internal_error("%s: bad function", func_name);
282  }
283  else
284  {
285  list func_regions;
286 
287  /* Get the regions of "func". */
288  func_regions = effects_to_list((effects)
289  db_get_memory_resource(DBR_SUMMARY_REGIONS, func_name, true));
290  /* translate them */
291  le = regions_backward_translation(func, real_args, func_regions, context,
292  proper);
293  }
294  return le;
295 }
296 
297 list /* of effects */
299  list l_reg, transformer context)
300 {
301  list l_res = NIL;
302 
303  l_res = regions_backward_translation(func, real_args, l_reg, context, true);
304 
305  return l_res;
306 }
307 
308 list /* of effects */
310  list l_reg, transformer context)
311 {
312  list l_res = NIL;
313 
315  l_res = regions_forward_translation(callee, real_args, l_reg, context);
317  l_res = generic_c_effects_forward_translation(callee, real_args, l_reg, context);
318  return l_res;
319 }
320 
321 
322 /***************************************************** BACKWARD TRANSLATION */
323 
324 static list formal_regions_backward_translation(entity func, list real_args,
325  list func_regions,
327 static list common_regions_backward_translation(entity func, list func_regions);
328 static list common_region_translation(entity func, region reg, bool backward);
329 
330 /* list regions_backward_tranlation(entity func, list real_args,
331  * list func_regions, transformer context)
332  * input : an external function func, and the list of real arguments used
333  * in the calling function.
334  * output : the corresponding list of regions, at call site.
335  * modifies : nothing.
336  * comment : The effects of "func" are computed into externals effects,
337  * ie. `translated'. The translation is made in two phases :
338  * _ regions on formal parameters
339  * _ regions on common parameters
340  */
342  list func_regions,
343  transformer context, bool proper)
344 {
345  list le = NIL;
346  list tce, tfe;
347 
348  ifdebug(4)
349  {
350  pips_debug(4,"Initial regions\n");
351  print_regions(func_regions);
352  }
353 
356 
357  /* Compute the regions on formal variables. */
358  tfe = formal_regions_backward_translation(func,real_args,func_regions,context);
359 
360  /* Compute the regions on common variables (static & global variables). */
361  tce = common_regions_backward_translation(func, func_regions);
362 
363  if (proper)
364  le = gen_nconc(tce,tfe);
365  else
366  le = RegionsMustUnion(tce, tfe, effects_same_action_p);
367 
368  /* FI: add local precondition (7 December 1992) */
369  le = regions_add_context(le, context);
370 
371  ifdebug(4)
372  {
373  pips_debug(4, " Translated_regions :\n");
374  print_regions(le);
375  }
376 
379  return(le);
380 }
381 
382 
383 /* static list formal_regions_backward_translation(entity func, list real_args,
384  * func_regions, transformer context)
385  * input : an external function func, its real arguments at call site
386  * (real_args),
387  * its summary regions (with formal args), and the calling context.
388  * output : the translated formal regions.
389  * modifies : ?
390  * comment :
391  *
392  * Algorithm :
393  * -----------
394  * let func_regions be the list of the regions on variables of func
395  * let real_regions be the list of the translated regions on common variables
396  *
397  * real_regions = empty
398  * FOR each expression real_exp IN real_args
399  * arg_num = number in the list of the function real arguments
400  * FOR each func_reg IN func_regions
401  * func_ent = entity of the region func_reg
402  * IF func_ent is the formal parameter numbered arg_num
403  * IF real_exp is an lhs (expression with one entity)
404  * real_reg = translation of the region func_reg
405  * real_regions = (real_regions) U {real_reg}
406  * ELSE
407  * real_regions = (real_regions) U
408  * (regions of the expression real_exp)
409  * ENDIF
410  * ENDIF
411  * ENDFOR
412  * ENDFOR
413  */
414 static list formal_regions_backward_translation(func, real_args, func_regions,
415  context)
416 entity func;
417 list real_args, func_regions;
419 {
420  list real_regions = NIL, r_args;
421  int arg_num;
422 
423  pips_debug(8, "begin\n");
424 
425  for (r_args = real_args, arg_num = 1; r_args != NIL;
426  r_args = CDR(r_args), arg_num++)
427  {
428  MAP(EFFECT, func_reg,
429  {
430  entity func_ent = region_entity(func_reg);
431 
432  /* If the formal parameter corresponds to the real argument then
433  * we perform the translation.
434  */
435  if (ith_parameter_p(func, func_ent, arg_num))
436  {
437  expression real_exp = EXPRESSION(CAR(r_args));
438  syntax real_syn = expression_syntax(real_exp);
439 
440  /* If the real argument is a reference to an entity, then we
441  * translate the regions of the corresponding formal parameter
442  */
443  if (syntax_reference_p(real_syn))
444  {
445  reference real_ref = syntax_reference(real_syn);
446  list real_inds = reference_indices(real_ref);
447  entity real_ent = reference_variable(real_ref);
448  region real_reg;
449  real_reg =
450  region_translation(func_reg, func, reference_undefined,
451  real_ent, get_current_module_entity(), real_ref,
453 
454  real_regions = regions_add_region(real_regions, real_reg);
455  /* The indices of the reference are always evaluated */
456  if (! ENDP(real_inds))
457  real_regions = gen_nconc
458  (real_regions,
460  }
461  /* Else, the real argument is a complex expression, which
462  * is merely evaluated during execution of the program;
463  * Since Fortran forbids write effects on expressions
464  * passed as arguments, the regions on the formal parameter
465  * are merely ignored. The regions computed are those of the
466  * real parameter expression.
467  */
468  else
469  {
470  real_regions =
471  gen_nconc(real_regions,
473  }
474  }
475  }, func_regions);
476  }
477 
478  ifdebug(5)
479  {
480  pips_debug(5, "proper real regions\n");
481  print_regions(real_regions);
482  }
483  return(real_regions);
484 }
485 
487 {
488  list real_regions = NIL;
489 
490  MAP(EFFECT, func_reg,
491  {
492  /* we are only interested in regions concerning common variables.
493  * They are the entities with a ram storage. They can not be dynamic
494  * variables, because these latter were eliminated of the code_regions
495  * (cf. region_of_module). */
497  {
498  list regs = common_region_translation(func, func_reg, BACKWARD);
499  real_regions = RegionsMustUnion(real_regions, regs,
501  }
502  },
503  func_regions);
504 
505  return(real_regions);
506 
507 }
508 
509 
510 
511 /**
512 
513  @param l_sum_eff is a list of effects on a C function formal parameter. These
514  effects must be visible from the caller, which means that their
515  reference has at leat one index.
516  @param real_arg is an expression. It's the real argument corresponding to
517  the formal parameter which memory effects are represented by l_sum_eff.
518  @param context is the transformer translating the callee's neame space into
519  the caller's name space.
520  @return a list of effects which are the translation of l_sum_eff in the
521  caller's name space.
522  */
524  expression real_arg,
526 {
527  list l_eff = NIL; /* the result */
528  syntax real_s = expression_syntax(real_arg);
529  type real_arg_t = expression_to_type(real_arg);
530 
531 
532  ifdebug(5)
533  {
534  pips_debug(8, "begin for real arg %s, of type %s and effects :\n",
535  expression_to_string(real_arg),
536  type_to_string(real_arg_t));
537  (*effects_prettyprint_func)(l_sum_eff);
538  }
539 
540  switch (syntax_tag(real_s))
541  {
542  case is_syntax_reference:
543  {
544  reference real_ref = syntax_reference(real_s);
545  entity real_ent = reference_variable(real_ref);
546  list real_ind = reference_indices(real_ref);
547 
548  /* if it's a pointer or a partially indexed array
549  * We should do more testing here to check if types
550  * are compatible...
551  */
552 
553  /* the test here may not be right. I guess I should use basic_concrete_type here BC */
554  if (pointer_type_p(real_arg_t) ||
555  gen_length(real_ind) < type_depth(entity_type(real_ent)))
556  {
557  FOREACH(EFFECT, eff, l_sum_eff) {
558  reference new_ref = copy_reference(real_ref);
559  effect real_eff = effect_undefined;
560 
561  pips_debug(8, "pointer type real arg reference\n");
562 
563  /* Then we compute the region corresponding to the
564  * real argument
565  */
566  pips_debug(8, "effect on the pointed area : \n");
567  // functions that can be pointed by reference_to_effect_func:
568  // reference_to_simple_effect
569  // reference_to_convex_region
570  // reference_to_reference_effect
571  real_eff = (*reference_to_effect_func)
572  (new_ref, copy_action(effect_action(eff)), false);
573 
574  /* this could easily be made generic BC. */
575  /* FI: I add the restriction on store regions, but
576  * they should have been eliminated before translation
577  * is attempted */
578  if(!anywhere_effect_p(real_eff) && store_effect_p(real_eff))
579  {
580  reference n_eff_ref;
581  descriptor n_eff_d;
582  effect n_eff;
583  bool exact_translation_p;
584  // functions that can be pointed by effect_dup_func:
585  // simple_effect_dup
586  // region_dup
587  // copy_effect
588  effect init_eff = (*effect_dup_func)(eff);
589 
590  /* we translate the initial region descriptor
591  * into the caller's name space
592  */
594  /* and then perform the translation */
596  effect_descriptor(init_eff),
597  effect_any_reference(real_eff),
598  effect_descriptor(real_eff),
599  0,
600  &n_eff_ref, &n_eff_d,
601  &exact_translation_p);
602  n_eff = make_effect(make_cell_reference(n_eff_ref), copy_action(effect_action(eff)),
603  exact_translation_p? copy_approximation(effect_approximation(eff)) : make_approximation_may(),
604  n_eff_d);
605  /* shouldn't it be a union ? BC */
606  l_eff = gen_nconc(l_eff, CONS(EFFECT, n_eff, NIL));
607  free_effect(init_eff);
608  free_effect(real_eff);
609  }
610  }
611  } /* if (pointer_type_p(real_arg_t)) */
612  else
613  {
614  pips_debug(8, "real arg reference is not a pointer and is not a partially indexed array -> NIL \n");
615 
616  } /* else */
617  break;
618  } /* case is_syntax_reference */
619  case is_syntax_subscript:
620  {
621  pips_debug(8, "Subscript not supported yet -> anywhere");
622  bool read_p = false, write_p = false;
623  FOREACH(EFFECT, eff, l_sum_eff)
624  {
625  if(effect_write_p(eff)) write_p = true;
626  else read_p = true;
627  }
628 
629  if (write_p)
631  if (read_p)
633  break;
634  }
635  case is_syntax_call:
636  {
637  call real_call = syntax_call(real_s);
638  entity real_op = call_function(real_call);
639  list args = call_arguments(real_call);
640  effect n_eff = effect_undefined;
641 
642  if (ENTITY_ASSIGN_P(real_op))
643  {
645  (l_sum_eff, EXPRESSION(CAR(CDR(args))), context);
646  }
647  else if(ENTITY_ADDRESS_OF_P(real_op))
648  {
649  expression arg1 = EXPRESSION(CAR(args));
650  list l_real_arg = NIL;
651  list l_eff_real;
652 
653  /* first we compute an effect on the argument of the
654  * address_of operator (to treat cases like &(n->m))*/
655  pips_debug(6, "addressing operator case \n");
656 
657  l_real_arg =
659  (arg1, &l_eff_real, true);
660 
661  pips_debug_effects(6, "base effects :\n", l_eff_real);
662 
663  FOREACH(EFFECT, eff_real, l_eff_real)
664  {
665  FOREACH(EFFECT, eff, l_sum_eff) {
666  reference eff_ref = effect_any_reference(eff);
667  list eff_ind = reference_indices(eff_ref);
668 
669  pips_debug_effect(6, "current formal effect :\n", eff);
670 
671  if (effect_undefined_p(eff_real) || anywhere_effect_p(eff_real))
672  {
674  }
675  else
676  {
677  if(!ENDP(eff_ind))
678  {
679  // functions that can be pointed by effect_dup_func:
680  // simple_effect_dup
681  // region_dup
682  // copy_effect
683  effect eff_init = (*effect_dup_func)(eff);
684 
685  /* we translate the initial region descriptor
686  * into the caller's name space
687  */
689 
690  reference output_ref;
691  descriptor output_desc;
692  bool exact;
693 
695  (effect_any_reference(eff), effect_descriptor(eff_init),
696  effect_any_reference(eff_real), effect_descriptor(eff_real),
697  0,
698  &output_ref, &output_desc,
699  &exact);
700 
702  {
703  free_reference(output_ref);
705  }
706  else
707  {
708  n_eff = make_effect(make_cell_reference(output_ref),
711  output_desc);
712  pips_debug_effect(6, "resulting effect: \n", n_eff);
713  }
714  } /* if(!ENDP(eff_ind))*/
715  } /* else du if (effect_undefined_p(eff_real) || ...) */
716 
717  l_eff = gen_nconc(l_eff, CONS(EFFECT, n_eff, NIL));
718  } /* FOREACH(EFFECT, eff, l_sum_eff) */
719  } /* FOREACH (EFFECT, eff_real, l_eff_real) */
720 
721  gen_free_list(l_real_arg);
722  gen_full_free_list(l_eff_real);
723 
724  }
725  else if(ENTITY_DEREFERENCING_P(real_op))
726  {
727  // expression arg1 = EXPRESSION(CAR(args));
728 
729  pips_debug(6, "dereferencing operator case \n");
730 
731  /* if it's a pointer or a partially indexed array
732  * We should do more testing here to check if types
733  * are compatible...
734  */
735  if (pointer_type_p(real_arg_t) ||
736  !ENDP(variable_dimensions(type_variable(real_arg_t))))
737  {
738  pips_debug(8, "pointer type real arg\n");
739  /* first compute the region corresponding to the
740  * real argument
741  */
742  list l_real_eff = NIL;
743  list l_real_arg =
745  (real_arg, &l_real_eff, true);
746 
747  pips_debug_effects(6, "base effects :\n", l_real_eff);
748 
749  FOREACH(EFFECT, real_eff, l_real_eff)
750  {
751  FOREACH(EFFECT, eff, l_sum_eff) {
752  /* this could easily be made generic BC. */
753  /* FI: I add the restriction on store regions, but
754  * they should have been eliminated before translation
755  * is attempted */
756  if(!anywhere_effect_p(real_eff) && store_effect_p(real_eff))
757  {
758  reference n_eff_ref;
759  descriptor n_eff_d;
760  effect n_eff;
761  bool exact_translation_p;
762  // functions that can be pointed by effect_dup_func:
763  // simple_effect_dup
764  // region_dup
765  // copy_effect
766  effect init_eff = (*effect_dup_func)(eff);
767 
768  /* we translate the initial region descriptor
769  * into the caller's name space
770  */
772  /* and then perform the translation */
774  effect_descriptor(init_eff),
775  effect_any_reference(real_eff),
776  effect_descriptor(real_eff),
777  0,
778  &n_eff_ref, &n_eff_d,
779  &exact_translation_p);
780  n_eff = make_effect(make_cell_reference(n_eff_ref), copy_action(effect_action(eff)),
781  exact_translation_p? copy_approximation(effect_approximation(eff)) : make_approximation_may(),
782  n_eff_d);
783  /* shouldn't it be a union ? BC */
784  l_eff = gen_nconc(l_eff, CONS(EFFECT, n_eff, NIL));
785  free_effect(init_eff);
786  }
787  }
788  }
789  gen_free_list(l_real_arg);
790  gen_full_free_list(l_real_eff);
791 
792  } /* if (pointer_type_p(real_arg_t)) */
793  else
794  {
795  pips_debug(8, "real arg reference is not a pointer and is not a partially indexed array -> NIL \n");
796  } /* else */
797  break;
798  }
799  else if(ENTITY_POINT_TO_P(real_op)|| ENTITY_FIELD_P(real_op))
800  {
801  list l_real_arg = NIL;
802  list l_eff_real = NIL;
803  /* first we compute an effect on the real_arg */
804 
805  pips_debug(6, "point_to or field operator\n");
807  (real_arg, &l_eff_real, true);
808 
809  FOREACH(EFFECT, eff_real, l_eff_real)
810  {
811  FOREACH(EFFECT, eff, l_sum_eff) {
812  // functions that can be pointed by effect_dup_func:
813  // simple_effect_dup
814  // region_dup
815  // copy_effect
816  effect eff_formal = (*effect_dup_func)(eff);
817  effect new_eff;
818 
819  if (effect_undefined_p(eff_real))
821  else
822  {
823  // functions that can be pointed by effect_dup_func:
824  // simple_effect_dup
825  // region_dup
826  // copy_effect
827  new_eff = (*effect_dup_func)(eff_real);
828  effect_approximation_tag(new_eff) =
830  effect_action_tag(new_eff) =
831  effect_action_tag(eff);
832 
833 
834  /* first we translate the formal region predicate */
836 
837  /* Then we append the formal region to the real region */
838  /* Well this is valid only in the general case :
839  * we should verify that types are compatible. */
840  new_eff = region_append(new_eff, eff_formal);
841  free_effect(eff_formal);
842 
843  } /* else du if (effect_undefined_p(eff_real)) */
844 
845  /* shouldn't it be a union ? BC */
846  l_eff = gen_nconc(l_eff, CONS(EFFECT, new_eff, NIL));
847  } /* FOREACH(EFFECT, eff, l_sum_eff) */
848  }
849  gen_free_list(l_real_arg);
850  gen_full_free_list(l_eff_real);
851 
852  }
853  else if(ENTITY_MALLOC_SYSTEM_P(real_op))
854  {
855  /* BC : do not generate effects on HEAP */
856  /* n_eff = heap_effect(get_current_module_entity(),
857  * copy_action(effect_action(eff)));*/
858  }
859  else
860  {
861  l_eff = gen_nconc
862  (l_eff,
864  }
865 
866  if (n_eff != effect_undefined && l_eff == NIL)
867  l_eff = CONS(EFFECT,n_eff, NIL);
868  break;
869  } /* case is_syntax_call */
870  case is_syntax_cast :
871  {
872  pips_debug(5, "cast case\n");
873  expression cast_exp = cast_expression(syntax_cast(real_s));
874  type cast_t = expression_to_type(cast_exp);
875  /* we should test here the compatibility of the casted expression type with
876  * the formal entity type. It is not available here, however, I think it's
877  * equivalent to test the compatibility with the real arg expression type
878  * since the current function is called after testing the compatilibty between
879  * the real expression type and the formal parameter type.
880  */
882  {
883  l_eff = gen_nconc
884  (l_eff,
886  (l_sum_eff, cast_exp, context));
887  }
888  else if (!ENDP(l_sum_eff))
889  {
890  /* let us at least generate effects on all memory locations reachable from
891  * the cast expression
892  */
893  bool read_p = false, write_p = false;
894  FOREACH(EFFECT, eff, l_sum_eff)
895  {
896  if(effect_write_p(eff)) write_p = true;
897  else read_p = false;
898  }
899  tag t = write_p ? (read_p ? 'x' : 'w') : 'r';
900  l_eff = gen_nconc
901  (l_eff,
903  }
904 
905  break;
906  }
908  {
909  pips_debug(5,"sizeof expression -> NIL");
910  break;
911  }
912  case is_syntax_va_arg :
913  {
914  pips_internal_error("va_arg() : should have been treated before");
915  break;
916  }
917  case is_syntax_application :
918  {
919  bool read_p = false, write_p = false;
920  pips_user_warning("Application not supported yet -> anywhere effect\n");
921  FOREACH(EFFECT, eff, l_sum_eff)
922  {
923  if(effect_write_p(eff)) write_p = true;
924  else read_p = true;
925  }
926  if (write_p)
928  if (read_p)
930  break;
931  }
932  case is_syntax_range :
933  {
934  pips_user_error("Illegal effective parameter: range\n");
935  break;
936  }
937  default:
938  pips_internal_error("Illegal kind of syntax");
939  break;
940  } /* switch */
941 
942  /* free_type(real_arg_t); */
943 
945  // functions that can be pointed by effects_precondition_composition_op:
946  // effects_composition_with_preconditions_nop
947  // convex_regions_precondition_compose
948  (*effects_precondition_composition_op)(l_eff, context, false);
949  }
950  ifdebug(8)
951  {
952  pips_debug(8, "end with effects :\n");
953  print_regions(l_eff);
954  }
955 
956  return(l_eff);
957 }
958 
959 
960 
961 
962 /****************************************************** FORWARD TRANSLATION */
963 
964 
965 static list real_regions_forward_translation(entity func, list real_args,
966  list l_reg, transformer context);
967 static list common_regions_forward_translation(entity func, list real_regions);
968 
969 
970 /* list regions_forward_translation(entity func, list real_args, l_reg,
971  * transformer context
972  * input : the called function func, the real arguments of the call,
973  * the list of regions to translate, and the context of the call.
974  * output : the translated list of regions : real arguments are translated
975  * into formal arguments, and common variables of the caller into
976  * common variables of the callee.
977  * modifies : nothing.
978  * comment :
979  */
980 list regions_forward_translation(func, real_args, l_reg, context)
981 entity func;
982 list real_args, l_reg;
984 {
985  list l_t_reg = NIL;
986  list l_form_reg, l_common_reg;
987 
988  ifdebug(3)
989  {
990  pips_debug(3,"initial regions :\n");
991  print_regions(l_reg);
992  }
993 
996 
998  (func, real_args, l_reg, context);
999  l_common_reg = common_regions_forward_translation(func, l_reg);
1000  l_t_reg = RegionsMustUnion
1001  (l_form_reg, l_common_reg, effects_same_action_p);
1002 
1003  ifdebug(3)
1004  {
1005  pips_debug(3,"final regions : \n");
1006  print_regions(l_t_reg);
1007  }
1008 
1011  return l_t_reg;
1012 }
1013 
1014 
1015 /* static list real_regions_forward_translation(entity func, list real_args, l_reg,
1016  * transformer context)
1017  * input : the called function func, the real arguments of the call,
1018  * the list of regions to translate, and the context of the call.
1019  * output : the list of translated regions correponding to the formal arguments
1020  * of the called function.
1021  * modifies : l_reg and the regions it contains.
1022  * comment :
1023  * for each real argument in real_args
1024  * if it is a reference
1025  * for each region in l_reg
1026  * if the current region concerns the current real argument
1027  * if the corresponding formal parameter is a scalar
1028  * the translated region is a scalar region, which
1029  * reference is the formal argument, and which
1030  * action and approximation are those of the initial
1031  * region.
1032  * else it is an array,
1033  * and the tranlation is performed by
1034  * another procedure.
1035  * endfor
1036  * else, it is a complex expression
1037  * we search the regions in l_reg corresponding to
1038  * the elements accessed in the complex expression.
1039  * and we make a read region corresponding to the
1040  * formal scalar parameter.
1041  * endif
1042  * endfor
1043  *
1044  */
1045 static list real_regions_forward_translation(func, real_args, l_reg, context)
1046 entity func;
1047 list real_args, l_reg;
1049 {
1050  entity caller = get_current_module_entity();
1051  int arg_num;
1052  list l_formal = NIL;
1053  list r_args = real_args;
1054 
1055  /* for each actual parameter expression, we search in the actual regions
1056  * the corresponding elements. If it exists, we make the corresponding
1057  * regions, and translate them */
1058 
1059  ifdebug(8)
1060  {
1061  pips_debug(8,"initial regions :\n");
1062  print_regions(l_reg);
1063  }
1064 
1065  for (arg_num = 1; !ENDP(r_args); r_args = CDR(r_args), arg_num++)
1066  {
1067  expression real_exp = EXPRESSION(CAR(r_args));
1068  entity formal_ent = find_ith_formal_parameter(func, arg_num);
1069 
1070  if (syntax_reference_p(expression_syntax(real_exp)))
1071  {
1072  reference real_ref = syntax_reference(expression_syntax(real_exp));
1073  entity real_ent = reference_variable(real_ref);
1074 
1075  MAP(EFFECT, reg,
1076  {
1077  entity reg_ent = region_entity(reg);
1078 
1079  pips_debug(8, " real = %s, formal = %s \n",
1080  entity_name(real_ent), entity_name(reg_ent));
1081 
1082  if (same_entity_p(reg_ent , real_ent))
1083  {
1084  region formal_reg;
1085  formal_reg = region_translation(
1086  reg, caller, real_ref,
1087  formal_ent, func, reference_undefined,
1088  VALUE_ZERO, FORWARD);
1089  l_formal = RegionsMustUnion(
1090  l_formal,
1091  CONS(EFFECT, formal_reg, NIL),
1093  }
1094  }, l_reg);
1095 
1096  } /* if */
1097  else
1098  {
1099  /* REVOIR ICI */
1100  list l_exp_reg = regions_of_expression(real_exp, context);
1101  list l_real_exp =
1102  RegionsIntersection(l_exp_reg, effects_dup(l_reg),
1104 
1105  pips_debug(8, "real argument is a complex expression \n"
1106  "\tit can not correspond to a written formal parameter.\n");
1107 
1108  if (!ENDP(l_real_exp))
1109  {
1111  region formal_reg =
1113  free_action(r);
1114  effect_to_may_effect(formal_reg);
1115  l_formal = RegionsMustUnion(l_formal,
1116  CONS(EFFECT, formal_reg, NIL),
1118  regions_free(l_real_exp);
1119  }
1120 
1121  } /* else */
1122 
1123  } /* for */
1124 
1125 
1126  return(l_formal);
1127 }
1128 
1129 
1130 /* static list common_regions_forward_translation
1131  * (entity func, list real_regions)
1132  * input : the called function, the list of real arguments at call site, and
1133  * the list of regions to translate.
1134  * output : the translated list of regions.
1135  * modifies : nothing.
1136  * comment :
1137  */
1139 {
1140  list func_regions = NIL;
1141 
1142  MAP(EFFECT, real_reg,
1143  {
1144  storage real_s = entity_storage(region_entity(real_reg));
1145  /* we are only interested in regions concerning common variables.
1146  * They are the entities with a ram storagethat are not dynamic
1147  * variables*/
1148  if (storage_ram_p(real_s) &&
1150  && !heap_area_p(ram_section(storage_ram(real_s)))
1151  && !stack_area_p(ram_section(storage_ram(real_s))))
1152  {
1153  list regs = common_region_translation(func, real_reg, FORWARD);
1154  func_regions = RegionsMustUnion(func_regions, regs,
1156  }
1157  },
1158  real_regions);
1159 
1160  return(func_regions);
1161 }
1162 
1164 (entity callee, expression real_exp, entity formal_ent, list l_reg, transformer context)
1165 {
1166  syntax real_s = expression_syntax(real_exp);
1167  list l_formal = NIL;
1168 
1169  pips_debug_effects(6,"initial regions :\n", l_reg);
1170 
1171 
1172  switch (syntax_tag(real_s))
1173  {
1174  case is_syntax_call:
1175  {
1176  call real_call = syntax_call(real_s);
1177  entity real_op = call_function(real_call);
1178  list args = call_arguments(real_call);
1179  type uet = ultimate_type(entity_type(real_op));
1180  value real_op_v = entity_initial(real_op);
1181 
1182  pips_debug(5, "call case, function %s \n", module_local_name(real_op));
1183  if(type_functional_p(uet))
1184  {
1185  if (value_code_p(real_op_v))
1186  {
1187  pips_debug(5, "external function\n");
1188  pips_user_warning("Nested function calls are ignored. Consider splitting the code before running PIPS\n");
1189  l_formal = NIL;
1190  break;
1191  }
1192  else /* it's an intrinsic : FI, cannot it be a constant? */
1193  {
1194  pips_debug(5, "intrinsic function\n");
1195 
1196  if (ENTITY_ASSIGN_P(real_op))
1197  {
1198  pips_debug(5, "assignment case\n");
1200  (callee, EXPRESSION(CAR(CDR(args))), formal_ent, l_reg, context);
1201  break;
1202  }
1203  else if(ENTITY_ADDRESS_OF_P(real_op))
1204  {
1205  expression arg1 = EXPRESSION(CAR(args));
1206  list l_real_arg = NIL;
1207  effect eff_real;
1208  int nb_phi_real;
1209  Psysteme sc_nb_phi_real;
1210  expression exp_nb_phi_real = expression_undefined;
1211  bool general_case = true;
1212  bool in_out = in_out_methods_p();
1213 
1214  pips_debug(5, "address of case\n");
1215 
1216  /* first we compute a SIMPLE effect on the argument of the address_of operator.
1217  * This is to distinguish between the general case and the case where
1218  * the operand of the & operator is an array element.
1219  * Simple effect indices are easier to retrieve.
1220  */
1222  list l_eff_real = NIL;
1224  (arg1, &l_eff_real, true);
1225 
1226  eff_real = EFFECT(CAR(l_eff_real)); /* there should be a FOREACH here to scan the whole list */
1227  gen_free_list(l_eff_real);
1228 
1229  nb_phi_real = (int) gen_length(reference_indices(effect_any_reference(eff_real)));
1230  gen_full_free_list(l_real_arg);
1231 
1232  /* there are indices but we don't know if they represent array dimensions,
1233  * struct/union/enum fields, or pointer dimensions.
1234  */
1235  if(nb_phi_real > 0)
1236  {
1237  reference eff_real_ref = effect_any_reference(eff_real);
1238  list l_inds_real = NIL, l_tmp = NIL;
1239  reference ref_tmp;
1240  type t = type_undefined;
1241 
1242  for(l_inds_real = reference_indices(eff_real_ref); !ENDP(CDR(l_inds_real)); POP(l_inds_real))
1243  {
1244  l_tmp = gen_nconc(l_tmp, CONS(EXPRESSION, copy_expression(EXPRESSION(CAR(l_inds_real))), NIL));
1245  }
1246 
1247  ref_tmp = make_reference(reference_variable(eff_real_ref), l_tmp);
1248  t = simple_effect_reference_type(ref_tmp);
1249  free_reference(ref_tmp);
1250 
1251  if (type_undefined_p(t))
1252  pips_internal_error("undefined type not expected ");
1253 
1255  {
1256  pips_debug(5,"array element or sub-array case\n");
1257  general_case = false;
1258  /* we build the constraint PHI_nb_phi_real >= last index of eff_real */
1259  exp_nb_phi_real = copy_expression(EXPRESSION(CAR(l_inds_real))); // copy necessary because eff_real is freed afterwards
1260  sc_nb_phi_real = sc_new();
1261  (void) sc_add_phi_equation(&sc_nb_phi_real,
1262  copy_expression(exp_nb_phi_real),
1263  nb_phi_real, NOT_EG, NOT_PHI_FIRST);
1264  }
1265  else
1266  pips_debug(5, "general case\n");
1267  }
1268 
1269  free_effect(eff_real);
1270  eff_real = effect_undefined;
1271  /* well, not strictly necessary : forward propagation is only for OUT regions */
1272  if (in_out)
1274  else
1277 
1278  /* now we compute a *convex* effect on the argument of the
1279  * address_of operator and modify it's last dimension
1280  * according to the fact that there is an addressing operator
1281  */
1282 
1283  l_eff_real = NIL;
1285  (arg1, &l_eff_real, true);
1286  eff_real = EFFECT(CAR(l_eff_real)); /*There should be a FOREACH to handle all elements */
1287  gen_free_list(l_eff_real);
1288 
1289  gen_full_free_list(l_real_arg);
1290 
1291  if (!general_case)
1292  {
1293  /* array element operand : we replace the constraint on the last
1294  * phi variable with */
1295  entity phi_nb_phi_real = make_phi_entity(nb_phi_real);
1296  region_exact_projection_along_variable(eff_real, phi_nb_phi_real);
1297  region_sc_append_and_normalize(eff_real, sc_nb_phi_real, 1);
1298  (void) sc_free(sc_nb_phi_real);
1299  }
1300 
1301  FOREACH(EFFECT, eff_orig, l_reg)
1302  {
1303  int nb_phi_orig = (int) gen_length(reference_indices(effect_any_reference(eff_orig)));
1304 
1305  /* First we have to test if the eff_real access path leads to the eff_orig access path */
1306 
1307  /* to do that, if the entities are the same (well in fact we should also
1308  * take care of aliasing), we add the constraints of eff_real to those of eff_orig,
1309  * and the system must be feasible.
1310  * We should also take care of linearization here.
1311  */
1312  bool exact_p;
1313  if(path_preceding_p(eff_real, eff_orig, transformer_undefined, false, &exact_p))
1314  {
1315  // functions that can be pointed by effect_dup_func:
1316  // simple_effect_dup
1317  // region_dup
1318  // copy_effect
1319  effect eff_formal = (*effect_dup_func)(eff_orig);
1320  region_sc_append_and_normalize(eff_formal, region_system(eff_real), 1);
1321 
1322  if (sc_empty_p(region_system(eff_formal)))
1323  {
1324  pips_debug(5, "the original effect does not correspond to the actual argument \n");
1325  free_effect(eff_formal);
1326  }
1327  else
1328  {
1329  /* I guess we could reuse convex_cell_reference_with_address_of_cell_reference_translation */
1330  /* At least part of the original effect corresponds to the actual argument :
1331  * we need to translate it
1332  */
1333  Psysteme sc_formal;
1334  reference ref_formal = effect_any_reference(eff_formal);
1335  reference new_ref;
1336  list new_inds = NIL;
1337  int i, min_phi, min_i;
1338 
1339  pips_debug_effect(5, "matching access paths, considered effect is : \n", eff_formal);
1340 
1341  /* first we translate the predicate in the callee's name space */
1343  pips_debug_effect(5, "eff_formal after context translation: \n", eff_formal);
1344 
1345  /* Then we remove the phi variables common to the two regions
1346  * except the last one if we are not in the general case */
1347  /* This is only valid when there is no linearization ; in the general case
1348  * a translation system should be built
1349  */
1350  sc_formal = region_system(eff_formal);
1351  for(i = 1; i <= nb_phi_real; i++)
1352  {
1353  entity phi_i = make_phi_entity(i);
1354  entity psi_i = make_psi_entity(i);
1355 
1356  sc_formal = sc_variable_rename(sc_formal, (Variable) phi_i, (Variable) psi_i);
1357  }
1358  /* if not in the general case, we add the constraint
1359  * phi_nb_phi_real == psi_nb_phi_real - exp_nb_phi_real
1360  */
1361  if (!general_case)
1362  {
1363  entity phi = make_phi_entity(nb_phi_real);
1364  Pvecteur v_phi = vect_new((Variable) phi, VALUE_ONE);
1365  entity psi = make_psi_entity(nb_phi_real);
1366  Pvecteur v_psi = vect_new((Variable) psi, VALUE_ONE);
1367  Pvecteur v = vect_substract(v_phi, v_psi);
1368  normalized nexp = NORMALIZE_EXPRESSION(exp_nb_phi_real);
1369  if (normalized_linear_p(nexp))
1370  {
1371  pips_debug(6, "normalized last index : "
1372  "adding phi_nb_phi_real == psi_nb_phi_real - exp_nb_phi_real \n");
1373  Pvecteur v1 = vect_copy(normalized_linear(nexp));
1374  Pvecteur v2;
1375  v2 = vect_add(v, v1);
1376  sc_formal = sc_constraint_add(sc_formal, contrainte_make(v2), true);
1377  vect_rm(v1);
1378  }
1379  vect_rm(v_psi);
1380  vect_rm(v);
1381  }
1382  region_system(eff_formal) = sc_formal;
1383  pips_debug_effect(5, "eff_formal before removing psi variables: \n", eff_formal);
1384  region_remove_psi_variables(eff_formal);
1385  pips_debug_effect(5, "eff_formal after renaming common dimensions: \n", eff_formal);
1386 
1387  /* Finally, we must rename remaining phi variables from 2
1388  * add a PHI1==0 constraint in the general case,
1389  * or, in the contrary, rename remaining phi variables from 1.
1390  * We must also change the resulting region
1391  * entity for the formal entity in all cases.
1392  */
1393  min_phi = general_case? 2:1;
1394  min_i = general_case ? nb_phi_real+1 : nb_phi_real;
1395  sc_formal = region_system(eff_formal);
1396 
1397  pips_debug(8, "nb_phi_real: %d, min_i: %d, min_phi: %d\n", nb_phi_real, min_i, min_phi);
1398  for(i = min_i; i <= nb_phi_orig; i++)
1399  {
1400  pips_debug(8, "renaming %d-th index into %d-th\n", i, i-min_i+min_phi);
1401  entity phi_i = make_phi_entity(i);
1402  entity psi_formal = make_psi_entity(i-min_i+min_phi);
1403 
1404  // the call to gen_nth is rather costly
1405  expression original_index_exp =
1406  EXPRESSION( gen_nth(i-1, cell_indices(effect_cell(eff_orig))));
1407 
1408  pips_assert("index expression of an effect must be a reference",
1409  expression_reference_p(original_index_exp));
1410  if (entity_field_p(reference_variable(expression_reference(original_index_exp))))
1411  {
1412  pips_debug(8, "field expression (%s)\n",
1413  entity_name(reference_variable(expression_reference(original_index_exp))));
1414  new_inds = gen_nconc(new_inds,
1415  CONS(EXPRESSION,
1416  copy_expression(original_index_exp),
1417  NIL));
1418  }
1419  else
1420  {
1421  pips_debug(8, "phi expression \n");
1422  sc_formal = sc_variable_rename(sc_formal, (Variable) phi_i, (Variable) psi_formal);
1423 
1424  new_inds = gen_nconc(new_inds,
1425  CONS(EXPRESSION,
1426  make_phi_expression(i-nb_phi_real+1),
1427  NIL));
1428  }
1429 
1430  }
1431  for(i=min_phi; i<= nb_phi_orig-min_i+min_phi; i++)
1432  {
1433  entity phi_i = make_phi_entity(i);
1434  entity psi_i = make_psi_entity(i);
1435  sc_formal = sc_variable_rename(sc_formal, (Variable) psi_i, (Variable) phi_i);
1436  }
1437  region_system(eff_formal) = sc_formal;
1438  pips_debug_effect(5, "eff_formal after shifting dimensions: \n", eff_formal);
1439 
1440  if(general_case)
1441  {
1442  /* add PHI1 == 0 */
1443  sc_formal = region_system(eff_formal);
1444  (void) sc_add_phi_equation(&sc_formal, int_to_expression(0), 1, IS_EG, PHI_FIRST);
1445  region_system(eff_formal) = sc_formal;
1446  new_inds = CONS(EXPRESSION, make_phi_expression(1), new_inds);
1447  }
1448 
1449  free_reference(ref_formal);
1450  new_ref = make_reference(formal_ent, new_inds);
1451  cell_reference(effect_cell(eff_formal)) = new_ref;
1452  pips_debug_effect(5, "final eff_formal : \n", eff_formal);
1453  l_formal = RegionsMustUnion(l_formal, CONS(EFFECT, eff_formal, NIL),
1455  pips_debug_effects(6,"l_formal after adding new effect : \n", l_formal);
1456 
1457  } /* else of the if (sc_empty_p) */
1458 
1459  } /* if(effect_entity(eff_orig) == effect_entity(eff_real) ...)*/
1460 
1461  } /* FOREACH */
1462 
1463  if (!expression_undefined_p(exp_nb_phi_real))
1464  free_expression(exp_nb_phi_real);
1465  break;
1466  }
1467  else
1468  {
1469  pips_debug(5, "Other intrinsic case : entering general case \n");
1470  }
1471  }
1472  }
1473  else if(type_variable_p(uet))
1474  {
1475  pips_user_warning("Effects of call thru functional pointers are ignored\n");
1476  l_formal = NIL;
1477  break;
1478  }
1479  }
1480  // entering general case which includes general calls
1481  _FALLTHROUGH_;
1482  case is_syntax_reference:
1483  case is_syntax_subscript:
1484  {
1485  effect eff_real = effect_undefined;
1486 
1487  pips_debug(5, "general case\n");
1488 
1489  /* first we compute an effect on the real_arg */
1490  if (syntax_reference_p(real_s))
1492  else
1493  {
1494  list l_eff_real = NIL;
1496  (real_exp, &l_eff_real, true);
1497  gen_full_free_list(l_real_arg);
1498  if (!ENDP(l_eff_real))
1499  eff_real = EFFECT(CAR(l_eff_real)); /*there should be a foreach to scan all the elements */
1500  gen_free_list(l_eff_real);
1501  }
1502 
1503  if (!effect_undefined_p(eff_real))
1504  {
1505  FOREACH(EFFECT, eff_orig, l_reg)
1506  {
1507  int nb_phi_orig = (int) gen_length(reference_indices(effect_any_reference(eff_orig)));
1508  int nb_phi_real = (int) gen_length(reference_indices(effect_any_reference(eff_real)));
1509  /* First we have to test if the eff_real access path leads to the eff_orig access path */
1510 
1511  /* to do that, if the entities are the same (well in fact we should also
1512  take care of aliasing), we add the constraints of eff_real to those of eff_orig,
1513  and the system must be feasible.
1514  */
1515 
1516  bool exact_p;
1517  if(path_preceding_p(eff_real, eff_orig, transformer_undefined, true, &exact_p)
1518  && nb_phi_orig >= nb_phi_real)
1519  {
1520  effect eff_orig_dup = (*effect_dup_func)(eff_orig);
1521  region_sc_append_and_normalize(eff_orig_dup, region_system(eff_real), 1);
1522 
1523  if (sc_empty_p(region_system(eff_orig_dup)))
1524  {
1525  pips_debug(5, "the original effect does not correspond to the actual argument \n");
1526  free_effect(eff_orig_dup);
1527  }
1528  else
1529  {
1530  /* At least part of the original effect corresponds to the actual argument :
1531  we need to translate it
1532  */
1533  reference ref_formal = make_reference(formal_ent, NIL);
1534  effect eff_formal = make_reference_region(ref_formal, copy_action(effect_action(eff_orig)));
1535 
1536  pips_debug_effect(5, "matching access paths, considered effect is : \n", eff_orig_dup);
1537 
1538  /* first we perform the path translation */
1539  reference n_eff_ref;
1540  descriptor n_eff_d;
1541  effect n_eff;
1542  bool exact_translation_p;
1544  effect_descriptor(eff_orig_dup),
1545  ref_formal,
1546  effect_descriptor(eff_formal),
1547  nb_phi_real,
1548  &n_eff_ref, &n_eff_d,
1549  &exact_translation_p);
1550  n_eff = make_effect(make_cell_reference(n_eff_ref), copy_action(effect_action(eff_orig)),
1551  exact_translation_p? copy_approximation(effect_approximation(eff_orig)) : make_approximation_may(),
1552  n_eff_d);
1553  pips_debug_effect(5, "final eff_formal : \n", n_eff);
1554 
1555  /* then we translate the predicate in the callee's name space */
1557  pips_debug_effect(5, "eff_formal after context translation: \n", n_eff);
1558 
1559  l_formal = RegionsMustUnion(l_formal, CONS(EFFECT, n_eff, NIL),effects_same_action_p);
1560  pips_debug_effects(6, "l_formal after adding new effect : \n", l_formal);
1561  } /* else of the if (sc_empty_p) */
1562 
1563  } /* if(effect_entity(eff_orig) == effect_entity(eff_real) ...)*/
1564 
1565 
1566 
1567  /* */
1568 
1569  } /* FOREACH */
1570  }
1571 
1572  break;
1573  }
1574  case is_syntax_application:
1575  {
1576  pips_internal_error("Application not supported yet");
1577  break;
1578  }
1579 
1580  case is_syntax_cast:
1581  {
1582  pips_debug(6, "cast expression\n");
1583  type formal_ent_type = entity_basic_concrete_type(formal_ent);
1584  expression cast_exp = cast_expression(syntax_cast(real_s));
1585  type cast_exp_type = expression_to_type(cast_exp);
1587  {
1588  l_formal =
1590  (callee, cast_exp,
1591  formal_ent, l_reg, context);
1592  }
1593  else
1594  {
1595  expression formal_exp = entity_to_expression(formal_ent);
1596  l_formal = c_actual_argument_to_may_summary_effects(formal_exp, 'w');
1597  free_expression(formal_exp);
1598  }
1599  free_type(cast_exp_type);
1600  break;
1601  }
1602  case is_syntax_range:
1603  {
1604  pips_user_error("Illegal effective parameter: range\n");
1605  break;
1606  }
1607 
1609  {
1610  pips_debug(6, "sizeofexpression : -> NIL");
1611  l_formal = NIL;
1612  break;
1613  }
1614  case is_syntax_va_arg:
1615  {
1616  pips_internal_error("va_arg not supported yet");
1617  break;
1618  }
1619  default:
1620  pips_internal_error("Illegal kind of syntax");
1621 
1622  } /* switch */
1623 
1624 
1625  pips_debug_effects(6,"resulting regions :\n", l_formal);
1626  return(l_formal);
1627 
1628 }
1629 
1630 
1631 
1632 /********************************************************* COMMON FUNCTIONS */
1633 
1634 
1635 /* static list common_region_translation(entity func, region reg,
1636  * bool backward)
1637  * input : func is the called function, real_args are the real arguments,
1638  * reg is the region to translate (it concerns an array in a common),
1639  * and backward indicates the direction of the translation.
1640  * output : a list of regions, that are the translation of the initial region.
1641  * modifies : nothing: duplicates the original region.
1642  * comment : the algorithm is the following
1643  *
1644  * Scan the variables of the common that belong to the target function
1645  * For each variable do
1646  * if it has elements in common with the variable of the initial region
1647  * if both variables have the same layout in the common
1648  * perform the translation using array_region-translation
1649  * else
1650  * use the subscript values, and take into account the relative
1651  * offset of the variables in the common
1652  * add to the translated region the declaration system of the
1653  * target variable to have a smaller region.
1654  * until all the elements of the initial variable have been translated.
1655  */
1657  bool backward)
1658 {
1659  list new_regions = NIL;
1660  entity reg_ent = region_entity(reg);
1661  entity caller = get_current_module_entity();
1662  entity source_func = backward ? callee : caller;
1663  entity target_func = backward ? caller : callee;
1664  entity entity_target_func = target_func;
1665  entity ccommon;
1666  list l_tmp, l_com_ent;
1667  int reg_ent_size, total_size, reg_ent_begin_offset, reg_ent_end_offset;
1668  region new_reg;
1669  bool found = false;
1670 
1671 
1672  ifdebug(5)
1673  {
1674  pips_debug(5,"input region: \n%s\n", region_to_string(reg));
1675  }
1676 
1677  /* If the entity is a top-level entity, no translation;
1678  * It is the case for variables dexcribing I/O effects (LUNS).
1679  */
1680 
1681  if (top_level_entity_p(reg_ent) || io_entity_p(reg_ent)
1682  || rand_effects_entity_p(reg_ent))
1683  {
1684  pips_debug(5,"top-level entity.\n");
1685  new_reg = region_translation
1686  (reg, source_func, reference_undefined,
1687  reg_ent, target_func, reference_undefined,
1688  0, backward);
1689  new_regions = CONS(EFFECT, new_reg, NIL);
1690  return(new_regions);
1691  }
1692 
1693 
1694 
1695  ifdebug(6)
1696  {
1697  pips_debug(5, "target function: %s (local name: %s)\n",
1698  entity_name(target_func), module_local_name(target_func));
1699  }
1700 
1701  /* First, we search if the common is declared in the target function;
1702  * if not, we have to deterministically choose an arbitrary function
1703  * in which the common is declared. It will be our reference.
1704  * By deterministically, I mean that this function shall be chosen whenever
1705  * we try to translate from this common to a routine where it is not
1706  * declared.
1707  */
1708  ccommon = ram_section(storage_ram(entity_storage(reg_ent)));
1709  l_com_ent = area_layout(type_area(entity_type(ccommon)));
1710 
1711  pips_debug(6, "common name: %s\n", entity_name(ccommon));
1712 
1713  for( l_tmp = l_com_ent; !ENDP(l_tmp) && !found; l_tmp = CDR(l_tmp) )
1714  {
1715  entity com_ent = ENTITY(CAR(l_tmp));
1716  if (strcmp(entity_module_name(com_ent),
1717  module_local_name(target_func)) == 0)
1718  {
1719  found = true;
1720  }
1721  }
1722 
1723  /* If common not declared in caller, use the subroutine of the first entity
1724  * that appears in the common layout. (not really deterministic: I should
1725  * take the first name in lexical order. BC.
1726  */
1727  if(!found)
1728  {
1729  entity ent = ENTITY(CAR(l_com_ent));
1730  entity_target_func =
1732  ifdebug(6)
1733  {
1734  pips_debug(6, "common not declared in caller,\n"
1735  "\t using %s declarations instead\n",
1736  entity_name(entity_target_func));
1737  }
1738  }
1739 
1740  /* first, we calculate the offset and size of the region entity */
1741  reg_ent_size = array_size(reg_ent);
1742  reg_ent_begin_offset = ram_offset(storage_ram(entity_storage(reg_ent)));
1743  reg_ent_end_offset = reg_ent_begin_offset + reg_ent_size - 1;
1744 
1745  pips_debug(6,
1746  "\n\treg_ent: size = %d, offset_begin = %d, offset_end = %d\n",
1747  reg_ent_size, reg_ent_begin_offset, reg_ent_end_offset);
1748 
1749  /* then, we perform the translation */
1750  ccommon = ram_section(storage_ram(entity_storage(reg_ent)));
1751  l_com_ent = area_layout(type_area(entity_type(ccommon)));
1752  total_size = 0;
1753 
1754  for(; !ENDP(l_com_ent) && (total_size < reg_ent_size);
1755  l_com_ent = CDR(l_com_ent))
1756  {
1757  entity new_ent = ENTITY(CAR(l_com_ent));
1758 
1759  pips_debug(6, "current entity: %s\n", entity_name(new_ent));
1760 
1761  if (strcmp(entity_module_name(new_ent),
1762  module_local_name(entity_target_func)) == 0)
1763  {
1764  int new_ent_size = array_size(new_ent);
1765  int new_ent_begin_offset =
1767  int new_ent_end_offset = new_ent_begin_offset + new_ent_size - 1;
1768 
1769  pips_debug(6, "\n\t new_ent: size = %d, "
1770  "offset_begin = %d, offset_end = %d \n",
1771  new_ent_size, new_ent_begin_offset, new_ent_end_offset);
1772 
1773  if ((new_ent_begin_offset <= reg_ent_end_offset) &&
1774  (reg_ent_begin_offset <= new_ent_end_offset ))
1775  /* these entities have elements in common */
1776  {
1777  int offset = reg_ent_begin_offset - new_ent_begin_offset;
1778 
1779  new_reg = region_translation
1780  (reg, source_func, reference_undefined,
1781  new_ent, target_func, reference_undefined,
1782  (Value) offset, backward);
1783  new_regions = RegionsMustUnion(new_regions,
1784  CONS(EFFECT, new_reg, NIL),
1786  total_size += min (reg_ent_begin_offset,new_ent_end_offset)
1787  - max(reg_ent_begin_offset, new_ent_begin_offset) + 1;
1788  }
1789  }
1790  }
1791 
1792  ifdebug(5)
1793  {
1794  pips_debug(5, "output regions: \n");
1795  print_regions(new_regions);
1796  }
1797  return(new_regions);
1798 }
1799 
1800 
1801 
1802 
1803 
1804 
cell make_cell_reference(reference _field_)
Definition: effects.c:293
action copy_action(action p)
ACTION.
Definition: effects.c:77
void free_effect(effect p)
Definition: effects.c:451
void free_action(action p)
Definition: effects.c:80
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
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
static const char * caller_name
Definition: alias_check.c:122
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
#define VALUE_ZERO
void const char const char const int
int Value
#define VALUE_ONE
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
Pcontrainte contrainte_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
#define region_entity(reg)
#define region_system(reg)
#define region
simulation of the type region
list RegionsMustUnion(list l1, list l2, bool(*union_combinable_p)(effect, effect))
list RegionsMustUnion(list l1, list l2, union_combinable_p) input : two lists of regions output : a l...
list RegionsMayUnion(list l1, list l2, bool(*union_combinable_p)(effect, effect))
list RegionsMayUnion(list l1, list l2, union_combinable_p) input : two lists of regions output : a li...
list RegionsIntersection(list l1, list l2, bool(*intersection_combinable_p)(effect, effect))
list RegionsIntersection(list l1,l2, bool (*intersection_combinable_p)(effect, effect)) input : outpu...
void reset_out_summary_regions_list()
static list common_region_translation(entity func, region reg, bool backward)
static list common_region_translation(entity func, region reg, bool backward) input : func is the cal...
void out_regions_from_call_site_to_callee(call c)
void out_regions_from_call_site_to_callee(call c) input : a potential call site for current_callee.
list regions_of_external(entity func, list real_args, transformer context, bool proper)
list regions_of_external(entity func, list real_args, transformer context) input : an external functi...
list c_convex_effects_on_formal_parameter_backward_translation(list l_sum_eff, expression real_arg, transformer context)
static statement current_stmt
void update_out_summary_regions_list(list l_out)
#define NOT_EG
#define NOT_PHI_FIRST
list regions_forward_translation(entity func, list real_args, list l_reg, transformer context)
list regions_forward_translation(entity func, list real_args, l_reg, transformer context input : the ...
void convex_regions_translation_end()
static list l_sum_out_reg
static bool stmt_filter(statement s)
#define PHI_FIRST
#define FORWARD
list regions_backward_translation(entity func, list real_args, list func_regions, transformer context, bool proper)
list regions_backward_tranlation(entity func, list real_args, list func_regions, transformer context)...
static list common_regions_backward_translation(entity func, list func_regions)
list get_out_summary_regions_list()
static list formal_regions_backward_translation(entity func, list real_args, list func_regions, transformer context)
static list formal_regions_backward_translation(entity func, list real_args, func_regions,...
list convex_regions_forward_translation(entity callee, list real_args, list l_reg, transformer context)
of effects
static entity current_callee
list out_regions_from_caller_to_callee(entity caller, entity callee)
list in_regions_of_external(entity func, list real_args, transformer context)
list in_regions_of_external(entity func, list real_args, transformer context) input : an external fun...
list convex_regions_backward_translation(entity func, list real_args, list l_reg, transformer context)
of effects
#define min(a, b)
list c_convex_effects_on_actual_parameter_forward_translation(entity callee, expression real_exp, entity formal_ent, list l_reg, transformer context)
#define IS_EG
package regions : Alexis Platonoff, 22 Aout 1990, Be'atrice Creusillet 10/94
#define BACKWARD
static list real_regions_forward_translation(entity func, list real_args, list l_reg, transformer context)
static list real_regions_forward_translation(entity func, list real_args, l_reg, transformer context)...
static list common_regions_forward_translation(entity func, list real_regions)
static list common_regions_forward_translation (entity func, list real_regions) input : the called fu...
void convex_regions_translation_init(entity callee, list real_args, bool backward_p)
jmp_buf overflow_error;
#define max(a, b)
static Value offset
Definition: translation.c:283
void convex_region_descriptor_translation(effect)
entity make_phi_entity(int)
void set_backward_arguments_to_eliminate(entity)
effect make_reference_region(reference, action)
void convex_cell_reference_with_address_of_cell_reference_translation(reference, descriptor, reference, descriptor, int, reference *, descriptor *, bool *)
void print_regions(list)
list regions_of_expression(expression, transformer)
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)
effect region_append(effect, effect)
void set_interprocedural_translation_context_sc(entity, list)
void reset_arguments_to_eliminate(void)
bool sc_add_phi_equation(Psysteme *, expression, int, bool, bool)
effect reference_whole_region(reference, action)
list proper_regions_of_expressions(list, transformer)
expression make_phi_expression(int)
list regions_add_context(list, transformer)
void region_exact_projection_along_variable(effect, entity)
string region_to_string(effect)
void set_methods_for_convex_in_out_effects(void)
Definition: methods.c:469
void init_convex_inout_prettyprint(const char *)
void region_remove_psi_variables(effect)
reference make_regions_reference(entity)
effect region_translation(effect, entity, reference, entity, entity, reference, Value, bool)
bool in_out_methods_p(void)
Definition: methods.c:476
void set_methods_for_convex_rw_effects(void)
Definition: methods.c:358
entity make_psi_entity(int)
list regions_add_region(list, effect)
void regions_free(list)
void reset_translation_context_sc(void)
#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)
list generic_c_effects_forward_translation(entity, list, list, transformer)
void reset_out_effects(void)
void reset_proper_rw_effects(void)
void set_proper_rw_effects(statement_effects)
void set_cumulated_rw_effects(statement_effects)
void set_out_effects(statement_effects)
list effects_dup(list)
void effect_to_may_effect(effect)
type simple_effect_reference_type(reference)
list generic_proper_effects_of_expression(expression)
list load_statement_out_regions(statement)
list c_actual_argument_to_may_summary_effects(expression, tag)
void reset_cumulated_rw_effects(void)
bool effects_same_action_p(effect, effect)
bool path_preceding_p(effect, effect, transformer, bool, bool *)
Definition: eval.c:132
void set_methods_for_proper_simple_effects(void)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define effect_approximation_tag(eff)
#define effect_write_p(eff)
#define SUMMARY
#define effect_action_tag(eff)
list cell_indices(cell)
Definition: effects.c:64
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
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
list effects_to_list(effects)
Definition: effects.c:209
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
#define cell_reference(x)
Definition: effects.h:469
#define effect_undefined_p(x)
Definition: effects.h:615
#define effect_action(x)
Definition: effects.h:642
#define effect_undefined
Definition: effects.h:614
#define effect_descriptor(x)
Definition: effects.h:646
#define effect_approximation(x)
Definition: effects.h:644
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
#define effect_cell(x)
Definition: effects.h:640
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
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
void gen_multi_recurse(void *o,...)
Multi recursion visitor function.
Definition: genClib.c:3428
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define list_undefined_p(c)
Return if a list is undefined.
Definition: newgen_list.h:75
#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
#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
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
Definition: database.c:755
#define 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 _FALLTHROUGH_
Definition: misc-local.h:238
#define pips_user_error
Definition: misc-local.h:147
int tag
TAG.
Definition: newgen_types.h:92
string expression_to_string(expression e)
Definition: expression.c:77
#define ENTITY_ASSIGN_P(e)
#define ENTITY_DEREFERENCING_P(e)
#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 rand_effects_entity_p(entity e)
Definition: entity.c:1152
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 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 io_entity_p(entity e)
Several implicit entities are declared to define the implicit effects of IO statements.
Definition: entity.c:1139
bool fortran_module_p(entity m)
Test if a module is in Fortran.
Definition: entity.c:2799
bool entity_module_p(entity e)
Definition: entity.c:683
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
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
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
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
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
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 ith_parameter_p(entity, entity, int)
returns true if v is the ith formal parameter of function f
Definition: util.c:125
string type_to_string(const type)
type.c
Definition: type.c:51
#define type_functional_p(x)
Definition: ri.h:2950
#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 transformer_undefined_p(x)
Definition: ri.h:2848
#define syntax_reference(x)
Definition: ri.h:2730
#define syntax_tag(x)
Definition: ri.h:2727
#define reference_undefined
Definition: ri.h:2302
#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 ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define syntax_cast(x)
Definition: ri.h:2739
#define type_variable(x)
Definition: ri.h:2949
#define entity_storage(x)
Definition: ri.h:2794
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
@ 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 call_domain
newgen_callees_domain_defined
Definition: ri.h:58
#define ram_section(x)
Definition: ri.h:2249
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define cast_expression(x)
Definition: ri.h:747
#define type_undefined_p(x)
Definition: ri.h:2884
#define entity_undefined
Definition: ri.h:2761
#define expression_undefined
Definition: ri.h:1223
#define entity_name(x)
Definition: ri.h:2790
#define area_layout(x)
Definition: ri.h:546
#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 expression_undefined_p(x)
Definition: ri.h:1224
#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 statement_number(x)
Definition: ri.h:2452
#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 statement_undefined
Definition: ri.h:2419
#define ram_offset(x)
Definition: ri.h:2251
#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
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
Psysteme sc_constraint_add(Psysteme sc, Pcontrainte c, bool equality)
Definition: sc_insert_eq.c:115
Psysteme sc_free(Psysteme in_ps)
Psysteme sc_free( in_ps ) AL 30/05/94 Free of in_ps.
Definition: sc_list.c:112
void module_to_value_mappings(entity m)
void module_to_value_mappings(entity m): build hash tables between variables and values (old,...
Definition: mappings.c:624
transformer load_statement_precondition(statement)
void reset_precondition_map(void)
void set_precondition_map(statement_mapping)
#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
void free_value_mappings(void)
Normal call to free the mappings.
Definition: value.c:1212
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
Pbase vect_copy(Pvecteur b)
direct duplication.
Definition: alloc.c:240
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