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 semantics
28  */
29 
30 #include <stdio.h>
31 #include <string.h>
32 /* #include <stdlib.h> */
33 
34 #include "genC.h"
35 
36 
37 #include "linear.h"
38 #include "ri.h"
39 #include "effects.h"
40 #include "ri-util.h"
41 #include "prettyprint.h"
42 #include "effects-util.h"
43 
44 #include "database.h"
45 #include "pipsdbm.h"
46 #include "resources.h"
47 
48 #include "misc.h"
49 
50 #include "effects-generic.h"
51 #include "effects-simple.h"
52 
53 #include "transformer.h"
54 
55 #include "semantics.h"
56 
57 /* What follows has to be updated!!!
58  *
59  * The SUMMARY_PRECONDITION of a module m is built incrementally when
60  * the preconditions of its CALLERS are computed. Each time a call site cs
61  * to m is encountered, the precondition for cs is augmented with equations
62  * between formal and actual integer arguments. The new precondition so
63  * obtained is chained to the other preconditions for m.
64  *
65  * In other word, SUMMARY_PRECONDITION is a list of preconditions containing
66  * each a relation between formal and actual parameter. Should it be called
67  * SUMMARY_PRECONDITIONS?
68  *
69  * Before using the list of preconditions for m, each precondition has to:
70  * - be translated to update references to variables in common; if they
71  * are visible in m, their entity names caller:x have to be replaced by
72  * m:x;
73  * - be projected to eliminate variables which are not recognized by m
74  * semantics analysis (i.e. they do not appear in its value mappings);
75  * - be replaced by their unique convex hull, which is the real module
76  * precondition.
77  *
78  * These steps cannot be performed in the caller because the callee's
79  * value mappings are unknown.
80  *
81  * Memory management:
82  * - transformers stored by add_module_call_site_precondition()
83  * are copies or modified copies of the precondition argument ;
84  * - transformers returned as module preconditions are not duplicated;
85  * it does not seem to matter for the time being because a module
86  * precondition should be used only once. Wait for the strange bugs...
87  * db_get_memory_resource() could be not PURE.
88  *
89  * Note: illegal request are made to pipsdbm()
90  */
91 
93 entity m;
94 {
95  transformer p;
96 
97  pips_assert("get_module_precondition",entity_module_p(m));
98 
99  if(db_resource_p(DBR_SUMMARY_PRECONDITION, module_local_name(m)))
100  p = (transformer) db_get_memory_resource(DBR_SUMMARY_PRECONDITION,
102  true);
103  else
105 
106  /* FI: this does not work because the summary preconditions is reset
107  each time it should be accumulated */
108  /*
109  if(check_resource_up_to_date(DBR_SUMMARY_PRECONDITION,
110  module_local_name(m))) {
111  p = (transformer) db_get_memory_resource(DBR_SUMMARY_PRECONDITION,
112  module_local_name(m),
113  true);
114  }
115  else {
116  p = transformer_undefined;
117  }
118  */
119 
120  return p;
121 }
122 
124 entity m;
125 transformer p;
126 {
127  /* module precondition */
128  transformer mp;
129  transformer new_mp;
130  /* cons * ef = code_effects(value_code(entity_initial(m))); */
131  list ef = load_summary_effects(m);
132 
133  pips_assert("add_module_call_site_precondition",entity_module_p(m));
134  pips_assert("add_module_call_site_precondition",
135  p != transformer_undefined);
136 
137  ifdebug(8) {
138  pips_debug(8,"begin\n");
139  pips_debug(8,"for module %s\n",
140  module_local_name(m));
141  pips_debug(8,"call site precondition %p:\n", p);
142  /* p might not be printable; it may (should!) contain formal parameters
143  of module m */
144  dump_transformer(p);
145  }
146 
147  /* keep only the interprocedural part of p that can be easily used
148  by m; this is non optimal because symbolic constants will be
149  lost; this is due to value mappings; new and old values should be
150  added to the mapping using the module precondition*/
151  p = precondition_intra_to_inter(m, p, ef);
152 
153  pips_debug(8, "filtered call site precondition:\n");
155 
156  mp = get_module_precondition(m);
157 
158  ifdebug(8) {
159  if (!transformer_undefined_p(mp)) {
160  pips_debug(8, "old module precondition:\n");
161  dump_transformer(mp);
162  }
163  else
164  pips_debug(8, "old module precondition undefined\n");
165  }
166 
168 
169  pips_debug(8, "new module precondition in current frame:\n");
171 
172  if (!transformer_undefined_p(mp)) {
173 
174  /* convert global variables in the summary precondition in the
175  * local frame as defined by value mappings (FI, 1 February
176  * 1994) */
177 
178  /* p is returned in the callee's frame; there is no need for a
179  * translation; the caller's frame should always contain the
180  * callee's frame by definition of effects;unfortunately, I do not
181  * remember *why* I added this translation; it was linked to a
182  * problem encountered with transformer and "invisible" variables,
183  * i.e. global variables which are indirectly changed by a
184  * procedure which does not see them; such variables receive an
185  * arbitrary existing global name; they may receive different
186  * names in different context, because there is no canonical name;
187  * each time, summary_precondition and summary_transformer are
188  * used, they must be converted in a unique frame, which can only
189  * be the frame of the current module.
190  *
191  * FI, 9 February 1994
192  */
194 
195  pips_debug(8, "old module precondition in current frame:\n");
196  ifdebug(8) dump_transformer(mp);
197 
198  if(transformer_identity_p(mp)) {
199  /* the former precondition represents the entire space :
200  * the new precondition must also represent the entire space
201  * BC, november 1994.
202  */
203  transformer_free(p);
204  new_mp = mp;
205  }
206  else
207  new_mp = transformer_convex_hull(mp, p);
208 
209  }
210  else {
211  /* the former precondition is undefined. The new precondition
212  * is defined by the current call site precondition
213  * BC, november 1994.
214  */
215  new_mp = p;
216  }
217 
218  pips_debug(8, "new module precondition in current frame:\n");
219  ifdebug(8) dump_transformer(new_mp);
220 
221  DB_PUT_MEMORY_RESOURCE(DBR_SUMMARY_PRECONDITION,
223  (char*) new_mp );
224 
225  pips_debug(8, "end\n");
226 }
227 
228 
229 ␌
230 /* returns a module's parameter's list */
231 
233 {
234  /* get unsorted list of formal analyzable parameters for f by declaration
235  filtering; these parameters may not be used by the callee's
236  semantics analysis, but we have no way to know it because
237  value mappings are not available */
238 
239  list formals = NIL;
240  list decl = list_undefined;
241 
242  pips_assert("f is a module",entity_module_p(f));
243 
245  MAPL(ce, {entity e = ENTITY(CAR(ce));
248  formals = CONS(ENTITY, e, formals);},
249  decl);
250 
251  return formals;
252 }
253 
254 bool
256 {
257  bool result = true;
258 
259  if (!ENDP(l)) {
260  entity e1 = ENTITY(CAR(l));
261  type t1 = entity_type(e1);
262  result = analyzable_scalar_entity_p(e1);
263 
264  MAP(ENTITY,el, {
265  if (result) {
266  type t = entity_type(el);
267  result = result && analyzable_scalar_entity_p(el)
268  && type_equal_p(t1, t);
269  }
270  },
271  CDR(l));
272  }
273  return result;
274 }
275 ␌
276 /* add_formal_to_actual_bindings(call c, transformer pre, entity caller):
277  *
278  * pre := pre U {f = expr }
279  * i i
280  * for all i such that formal f_i is an analyzable scalar variable and
281  * as far as expression expr_i is analyzable and of the same type
282  */
284 {
285  entity f = call_function(c);
286  list pc = call_arguments(c);
288  cons * ce;
289 
290  pips_debug(6, "begin for call to %s from %s, pre=%p\n",
291  module_local_name(f), module_local_name(caller), pre);
292  ifdebug(6) dump_transformer(pre);
293 
294  pips_assert("f is a module",
295  entity_module_p(f));
296  pips_assert("The precondition pre is defined",
297  pre != transformer_undefined);
298 
299  /* let's start a long, long, long MAPL, so long that MAPL is a pain */
300  for( ce = formals; !ENDP(ce); POP(ce)) {
301  entity fp = ENTITY(CAR(ce));
303  expression expr = find_ith_argument(pc, r);
304 
305  if(expr == expression_undefined)
306  pips_user_error("not enough args in call to %s from %s for formal parameter %s of rank %d\n",
308  module_local_name(caller),
309  entity_local_name(fp), r);
310  else {
311  /* type checking. You already know that fp is a scalar variable */
312  type tfp = entity_type(fp);
313  basic bfp = variable_basic(type_variable(tfp));
314  basic bexpr = basic_of_expression(expr);
315 
316  if(!same_basic_p(bfp, bexpr)) {
317  pips_user_warning("Type incompatibility (%s/%s) for formal parameter \"%s\""
318  " (rank %d)\nin call to \"%s\" from \"%s\"\n",
319  basic_to_string(bfp), basic_to_string(bexpr),
320  entity_local_name(fp), r,
322  }
323 
324  if(basic_tag(bfp)==basic_tag(bexpr)) {
325  /* Do not care about side effects on expressions: this is used to map
326  a caller precondition towards a callee summary precondition. */
329  /* tmp must be used instead of fp_new because fp_new does not
330  exist in the caller frame */
331  transformer t_expr = any_expression_to_transformer(tmp, expr,
333  false);
334 
335  t_expr = transformer_safe_value_substitute(t_expr, tmp, fp_new);
336  /* Likely memory leak for the initial pre */
337  pre = transformer_safe_image_intersection(pre, t_expr);
338  free_transformer(t_expr);
339  }
340  else {
341  /* ignore assocation */
342  pips_debug(6, "Full type incompatibility (%s/%s) for formal parameter %s (rank %d)"
343  " in call to %s from %s\n"
344  "Association ignored",
345  basic_to_string(bfp), basic_to_string(bexpr),
347  module_local_name(caller));
348  }
349  }
350  }
351 
352  free_arguments(formals);
353 
354  ifdebug(6) {
355  pips_debug(6, "new pre=%p\n", pre);
356  dump_transformer(pre);
357  pips_debug(6, "end for call to %s from %s\n", module_local_name(f),
358  module_local_name(caller));
359  }
360 
361  return pre;
362 }
363 
364 /* Take side effects into account:
365  *
366  * pre := (t(expr )...(t_expr ))(pre) U {f = expr }
367  * n 1 i i
368  * for all i such that formal f_i is an analyzable scalar variable and
369  * as far as expression expr_i is analyzable and of the same type.
370  *
371  * The algorithmic structure has to be different from the previous one.
372  *
373  * pre is modified by side effects.
374  */
376 {
377  entity f = call_function(c);
378  list args = call_arguments(c);
379 
381  transformer new_pre = transformer_apply(tf, pre);
382 
383  ifdebug(6) {
384  pips_debug(6, "new pre=%p\n", new_pre);
385  dump_transformer(new_pre);
386  pips_debug(6, "end for call to %s from %s\n", module_local_name(f),
387  module_local_name(caller));
388  }
389 
390  free_transformer(tf);
391 
392  return new_pre;
393 }
394 ␌
396  transformer pre,
397  list le) // effect list
398 {
399 #define DEBUG_PRECONDITION_INTRA_TO_INTER 1
400  list values = NIL;
401  list lost_values = NIL;
402  list preserved_values = NIL;
403  Psysteme r;
404  Pbase b;
405  cons * ca;
406 
408  {
410  "begin for call to %s\nwith precondition:\n",
412  /* precondition cannot be printed because equations linking formal
413  * parameters have been added to the real precondition
414  */
415  dump_transformer(pre);
416  }
417 
419 
420  /* make sure you do not export a (potentially) meaningless old value */
421  for( ca = transformer_arguments(pre); !ENDP(ca); POP(ca) )
422  {
423  entity e = ENTITY(CAR(ca));
424  entity e_old;
425 
426  /* Thru DATA statements, old values of other modules may appear */
430  "entitiy %s not belonging to module %s\n",
431  entity_name(e),
433  }
434 
435  e_old = entity_to_old_value(e);
436 
437  if(base_contains_variable_p(sc_base(r), (Variable) e_old))
438  lost_values = arguments_add_entity(lost_values,
439  e_old);
440  }
441 
443  {
445  "meaningless old value(s):\n");
446  dump_arguments(lost_values);
447  }
448 
449  /* get rid of old_values */
451  (pre, lost_values, /* sc_elim_redund */ /* no_elim */ sc_safe_normalize);
452 
453  gen_free_list(lost_values);
454 
455 
457 
458  /* get rid of pre's variables that do not appear in effects le */
459  /* we should not have to know about these internal objects, Psysteme
460  and Pvecteur! */
461  lost_values = NIL;
463  for(b = r->base; b != NULL; b = b->succ) {
464  entity v = (entity) vecteur_var(b);
465 
466  if(!entity_constant_p(v))
467  values = arguments_add_entity(values, v);
468  }
469 
470  /* build a list of values to suppress*/
471  if(true || fortran_language_module_p(callee)) {
472  /* get rid of variables that are not referenced, directly or indirectly,
473  by the callee; translate what you can */
474  pips_debug(9, "Module effect list:");
475  ifdebug(9) print_effects(le);
476 
477  for(ca = values; !ENDP(ca); POP(ca)) {
478  entity e = ENTITY(CAR(ca));
479  // FI: concrete effects are now killed by abstract effects
480  list l_callee =
482  // FI: the association with an abstract effect kills the
483  // translation process below
484  // list l_callee = (list) effects_entities_which_may_conflict_with_scalar_entity(le, e);
485  /* For clarity, all cases are presented */
487  /* No need to substitute or eliminate this value */
488  /* This is a short term improvement for partial_eval01-02
489  that works only for values local to the callee not for
490  values updated indirectedly by callees of "callee". */
491  /* It resulted in many core dumps in array privatization */
492  ;
493  }
494  else if (ENDP(l_callee)) { /* no conflicts */
495  lost_values = arguments_add_entity(lost_values, e);
497  "value %s lost according to effect list\n",
498  entity_name(e));
499  }
500  else {
501  /* list of conflicting entities */
502  entity e_callee = ENTITY(CAR(l_callee));
503  /* case 1: only one entity*/
504  if (gen_length(l_callee)==1) {
505  /* case 1.1: one conflicting integer entity */
506  if (analyzable_scalar_entity_p(e_callee)) {
507  if(e_callee != e) {
508  if(type_equal_p(entity_type(e_callee), entity_type(e))) {
510  e, e_callee);
513  "value %s substituted by %s according to effect list le:\n",
514  entity_name(e), entity_name(e_callee));
515  dump_arguments(lost_values);
516  }
517  }
518  else {
519  /* Type mismatch */
520  lost_values = arguments_add_entity(lost_values, e);
522  "value %s lost because non analyzable scalar entity\n",
523  entity_name(e));
524  }
525  }
526  }
527  /* case 1.22: one conflicting non analyzable scalar entity*/
528  else {
529  lost_values = arguments_add_entity(lost_values, e);
531  "value %s lost because non analyzable scalar entity\n",
532  entity_name(e));
533  }
534  }
535  else { /* case 2: at least 2 conflicting entities */
537  /* case 2.1: all entities have the same type,
538  according to mapping_values the subtitution
539  is made with the first list element e_callee*/
540  if(e_callee != e) {
542  e, e_callee);
545  "value %s substituted by %s the first element list according to effect list le:\n",
546  entity_name(e), entity_name(e_callee));
547  dump_arguments(lost_values);
548  }
549  }
550  }
551 
552  else { /* case 2.2: all entities do not have the same type*/
553  lost_values = arguments_add_entity(lost_values, e);
555  "value %s lost - list of conflicting entities with different types\n",
556  entity_name(e));
557  }
558  }
559  }
560 
561  }
562  }
563  else if(false && c_language_module_p(callee)) {
564  /* Get rid of variables local to the caller */
565  ;
566  }
567 
568  preserved_values = arguments_difference(values, lost_values);
569 
572  "values lost because they do not appear in the effect list le:\n");
573  dump_arguments(lost_values);
575  "values preserved because they do appear in the effect list le"
576  " and in the transformer basis:\n");
577  dump_arguments(preserved_values);
578  }
579 
580  /* Get rid of unused or untouched variables, even though they may
581  * appear as global variables or formal parameters
582  *
583  * This happens with automatically generated modules and for routine
584  * XERCLT in KIVA (Renault) because it has been emptied.
585  *
586  */
587  if(ENDP(preserved_values)) {
588  /* No information but feasibility can be preserved */
589  if(transformer_empty_p(pre)) {
590  /* Get rid of the basis and arguments to define the empty set */
591  free_transformer(pre);
592  pre = transformer_empty();
593  }
594  else{
595  /* No information: the all value space is OK */
596  free_transformer(pre);
597  pre = transformer_identity();
598  }
599  }
600  else {
602  (pre, lost_values, /* sc_elim_redund */ /* no_elim */ sc_safe_normalize);
603  }
604 
605  /* free the temporary list of entities */
606  gen_free_list(preserved_values);
607  gen_free_list(lost_values);
608  gen_free_list(values);
609 
610  /* get rid of arguments because they are meaningless for
611  a module precondition: v_new == v_old by definition */
613  transformer_arguments(pre) = NIL;
614 
617  "return pre=%p\n",pre);
618  dump_transformer(pre);
620  }
621 
622  return pre;
623 }
624 ␌
626 {
628  /* a copy of sc_base(s) is needed because translate_global_value()
629  modifies it at the same time */
630  Pbase b = (Pbase) vect_dup(sc_base(s));
631  Pbase bv;
632 
633  ifdebug(6) {
634  pips_debug(6, "Predicate for tf:\n");
635  sc_fprint(stderr, s, (char * (*)(Variable)) dump_value_name);
636  }
637 
638  for(bv = b; bv != NULL; bv = bv->succ) {
640 
641  }
642 
643  base_rm(b);
644 }
645 
646 /* Try to convert an value on a non-local variable into an value
647  * on a local variable using a guessed name (instead of a location
648  * identity: M and N declared as COMMON/FOO/M and COMMON/FOO/N
649  * are not identified as a unique variable/location).
650  *
651  * Mo more true: It might also fail to translate variable C:M into A:M if C is
652  * indirectly called from A thru B and if M is not defined in B.
653  *
654  * This routine is not too safe. It accepts non-translatable variable
655  * as input and does not refuse them, most of the time.
656  */
658 entity m;
659 transformer tf;
660 entity v;
661 {
662  storage store = storage_undefined;
663  ram r = ram_undefined;
665  entity section = entity_undefined;
666 
667  ifdebug(7) {
668  pips_debug(7, "begin v = %s and tf = %p\n", entity_name(v), tf);
669  }
670 
671 
672  if(v == NULL) {
673  pips_internal_error("Trying to translate TCST");
674  return;
675  }
676 
677  /* Filter out constant and values *local* to the current module */
678  if(value_entity_p(v) || entity_constant_p(v)) {
679  /* FI: to be modified to account for global values that have a name
680  * but that should nevertheless be translated on their canonical
681  * representant; this occurs for non-visible global variables
682  */
683  /* FI: to be completed later... 3 December 1993
684  entity var = value_to_variable(v);
685 
686  pips_debug(7,
687  "%s is translated into %s\n",
688  entity_name(v), entity_name(e));
689  transformer_value_substitute(tf, v, e);
690  */
691 
692  pips_debug(7, "end: No need to translate %s\n", entity_name(v));
693  return;
694  }
695 
696  /* Filter out old values: they are translated when the new value is
697  * encountered, and the new value has to appear if the old value does
698  * appear.
699  *
700  * Instead, old values could be translated into new values and processing
701  * could go on...
702  *
703  * FI, 26 October 1994
704  */
705  if(global_old_value_p(v)) {
706  pips_debug(7, "end: No need to translate %s yet\n",
707  entity_name(v));
708  return;
709  }
710 
711  store = entity_storage(v);
712 
713  pips_debug(7, "Trying to translate %s\n", entity_name(v));
714 
715  if(!storage_ram_p(store)) {
716  if(storage_rom_p(store)) {
717  pips_debug(7, "%s is not translatable: store tag %d\n",
718  entity_name(v), storage_tag(store));
719  /* Should it be projected? No, this should occur later for
720  * xxxx#init variables when the xxxx is translated. Or before if
721  * xxxx has been translated
722  */
723  return;
724  }
725  else
726  if(storage_formal_p(store)) {
727  pips_debug(7, "formal %s is not translatable\n",
728  entity_name(v));
729  return;
730  }
731  if(storage_return_p(store)) {
732  pips_debug(7, "return %s is not translatable\n",
733  entity_name(v));
734  return;
735  }
736  else
737  pips_internal_error("%s is not translatable: store tag %d",
738  entity_name(v), storage_tag(store));
739  }
740 
741  ifdebug(7) {
742  pips_debug(7, "let's do it for v = %s and tf =\n",
743  entity_name(v));
744  dump_transformer(tf);
745  }
746 
747  r = storage_ram(store);
748  rf = ram_function(r);
749  section = ram_section(r);
750 
751  if(rf != m && top_level_entity_p(section)) {
752  /* must be a common; dynamic and static area must
753  have been filtered out before */
754  entity e;
755  entity v_init = entity_undefined;
756  Psysteme sc = SC_UNDEFINED;
757  Pbase b = BASE_UNDEFINED;
758 
759  if(top_level_entity_p(v)) {
760  // No need to translate
761  return;
762  }
763 
764  /* try to find an equivalent entity by its name
765  (whereas we should use locations) */
766  /*
767  e = FindEntity(module_local_name(m),
768  entity_local_name(v));
769  e = value_alias(value_to_variable(v));
770  */
771  e = value_alias(v);
772  if(e == entity_undefined) {
773  /* no equivalent name found, get rid of v */
774  pips_debug(7, "No equivalent for %s in %s: project %s\n",
775  entity_name(v), entity_name(m), entity_name(v));
776  user_warning("translate_global_value",
777  "Information about %s lost,\n"
778  "check structure of common /%s/ in modules %s and %s\n",
780  module_local_name(m));
783  /* transformer_projection(tf, CONS(ENTITY, v_old, NIL)); */
784  (void) transformer_filter(tf, CONS(ENTITY, v_old, NIL));
785  }
787  return;
788  }
789 
790  if(!same_scalar_location_p(v, e)) {
791  /* no equivalent location found, get rid of v */
792  pips_debug(7, "No equivalent location for %s and %s: project %s\n",
793  entity_name(v), entity_name(e), entity_name(v));
795  user_warning("translate_global_value",
796  "Information about %s lost,\n"
797  "check structure of common /%s/ in modules %s and %s\n",
799  module_local_name(m));
802  transformer_projection(tf, CONS(ENTITY, v_old, NIL));
803  }
805  return;
806  }
807 
808  if(!type_equal_p(entity_type(v), entity_type(e))) {
809  /* no equivalent location found, get rid of v */
810  pips_debug(7, "Same location but different types for %s (%s) and %s (%s):"
811  " project both %s and %s\n",
814  entity_name(e), entity_name(v));
816  user_warning("translate_global_value",
817  "Information about %s lost,\n"
818  "check types for variables in common /%s/ in modules %s and %s\n",
820  module_local_name(m));
823  transformer_projection(tf, CONS(ENTITY, v_old, NIL));
824  }
827  transformer_filter(tf, CONS(ENTITY, e_old, NIL));
828  }
829  transformer_filter(tf, CONS(ENTITY, v, NIL));
830  transformer_filter(tf, CONS(ENTITY, e, NIL));
831  return;
832  }
833 
834  sc = (Psysteme)
836  b = sc_base(sc);
837  if(base_contains_variable_p(b, (Variable) e)) {
838  /* e has already been introduced and v eliminated;
839  this happens when a COMMON variable is
840  also passed as real argument */
841  /* FI: v may still appear in the constraints as in spice.f
842  (Perfect Club) and spice01.f (Validation) */
843  Pvecteur subst = vect_new((Variable) v, (Value) 1);
845  list args = CONS(ENTITY, v, NIL);
846 
847  vect_add_elem(&subst, (Variable) e, (Value) -1);
848  eq = contrainte_make(subst);
849  sc_add_egalite(sc, eq);
850 
854  Pvecteur subst_old = vect_new((Variable) v_old, (Value) 1);
856 
857  args = CONS(ENTITY, v_old, args);
858 
859  vect_add_elem(&subst_old, (Variable) e_old, (Value) -1);
860  eq_old = contrainte_make(subst_old);
861  sc_equation_add(sc, eq_old);
862  }
863 
864  pips_debug(7, "%s has already been translated into %s\n",
865  entity_name(v), entity_name(e));
866  if(!language_c_p(module_language(m))) {
867  user_warning("translate_global_value",
868  "Variable %s is probably aliased with a formal parameter"
869  " by the current call to %s from %s.\n"
870  "This is forbidden by the Fortran 77 standard.\n",
872  }
873  ifdebug(7) {
874  pips_debug(7,
875  "%s should again be translated into %s by projection of %s\n",
876  entity_name(v), entity_name(e), entity_name(v));
877  dump_transformer(tf);
878  }
879 
883  }
884 
885  tf = transformer_projection(tf, args);
886  gen_free_list(args);
887 
888  ifdebug(7) {
889  pips_debug(7, "After projection of %s\n",
890  entity_name(v));
891  dump_transformer(tf);
892  }
893  }
894  else {
895  pips_debug(7, "%s is translated into %s\n",
896  entity_name(v), entity_name(e));
898  }
899 
900  v_init = (entity)
903  (char *) NULL),
904  entity_domain);
905  if(v_init != entity_undefined) {
906  entity e_init = (entity)
909  (char *) NULL),
910  entity_domain);
911  if(e_init == entity_undefined) {
912  /* this cannot happen when the summary transformer
913  of a called procedure is translated because
914  the write effect in the callee that is implied
915  by v_init existence must have been passed
916  upwards and must have led to the creation
917  of e_init */
918  /* this should not happen when a caller
919  precondition at a call site is transformed
920  into a piece of a summary precondition for
921  the callee because v_init becomes meaningless;
922  at the callee's entry point, by definition,
923  e == e_init; v_init should have been projected
924  before
925  */
926  Psysteme r =
928 
929  if(base_contains_variable_p(sc_base(r), (Variable) v_init))
930  pips_internal_error("Cannot find value %s",
931  strdup(
932  concatenate(
937  (char *) NULL)));
938  else {
939  /* forget e_init: there is no v_init in tf */
940  ;
941  pips_debug(7, "%s is not used in tf\n",
942  entity_name(v_init));
943  }
944  }
945  else {
946  pips_debug(7, "%s is translated into %s\n",
947  entity_name(v), entity_name(e));
948  if(transformer_value_substitutable_p(tf, v_init, e_init))
949  transformer_value_substitute(tf, v_init, e_init);
950  else {
951  pips_user_error("Unsupported aliasing linked to %s and %s\n",
952  entity_name(v_init), entity_name(e_init));
953  }
954  }
955  }
956  else {
957  /* there is no v_init to worry about; v is not changed in
958  the caller (or its subtree of callees) */
959  }
960  }
961  else {
962  /* this value does not need to be translated */
963  }
964 }
965 
967 transformer pre;
968 list le;
969 {
970  MAPL(ce, {
971  expression e = EXPRESSION(CAR(ce));
973  },
974  le)
975  }
976 
978 transformer pre;
979 expression e;
980 {
981  syntax s = expression_syntax(e);
982 
983  if(syntax_call_p(s)) {
984  call c = syntax_call(s);
986  }
987 }
988 
990 transformer pre;
991 call c;
992 {
993  entity e = call_function(c);
994  tag tt;
995  list args = call_arguments(c);
996  transformer pre_callee = transformer_undefined;
997 
998  pips_debug(8, "begin\n");
999 
1000  switch (tt = value_tag(entity_initial(e))) {
1001 
1002  case is_value_intrinsic:
1003  pips_debug(5, "intrinsic function %s\n",
1004  entity_name(e));
1005  /* propagate precondition pre as summary precondition
1006  of user functions */
1008  break;
1009 
1010  case is_value_code:
1011  pips_debug(5, "external function %s\n",
1012  entity_name(e));
1013  pre_callee = transformer_dup(pre);
1014  pre_callee =
1016  add_module_call_site_precondition(e, pre_callee);
1017  /* propagate precondition pre as summary precondition
1018  of user functions */
1020  break;
1021 
1022  case is_value_symbolic:
1023  /* user_warning("call_to_summary_precondition",
1024  "call to symbolic %s\n",
1025  entity_name(e)); */
1026  break;
1027 
1028  case is_value_constant:
1029  user_warning("call_to_summary_precondition",
1030  "call to constant %s\n",
1031  entity_name(e));
1032  break;
1033 
1034  case is_value_unknown:
1035  pips_internal_error("unknown function %s",
1036  entity_name(e));
1037  break;
1038 
1039  default:
1040  pips_internal_error("unknown tag %d", tt);
1041  }
1042 
1043  pips_debug(8, "end\n");
1044 
1045 }
1046 
1047 /* This function does everything needed.
1048  * Called by ICFG with many different contexts.
1049  */
1050 text
1052  entity caller,
1053  entity callee,
1054  statement s,
1055  call c)
1056 {
1057  text result;
1058  /* summary effects for the callee */
1059  list seffects_callee = load_summary_effects(callee);
1060  /* caller preconditions */
1061  transformer caller_prec = transformer_undefined;
1062  /* callee preconditions */
1063  transformer call_site_prec = transformer_undefined;
1064 
1067  (DBR_CUMULATED_EFFECTS,
1068  module_local_name(caller), true));
1069 
1072  (DBR_PRECONDITIONS,
1073  module_local_name(caller),
1074  true) );
1075 
1076  /* load caller preconditions */
1077  caller_prec = transformer_dup(load_statement_semantic(s));
1078 
1080 
1081  /* first, we deal with the caller */
1082  set_current_module_entity(caller);
1083  /* create htable for old_values ... */
1084  module_to_value_mappings(caller);
1085 
1086  /* add to preconditions the links to the callee formal params */
1087  caller_prec = add_formal_to_actual_bindings (c, caller_prec, caller);
1088  /* transform the preconditions to make sense for the callee */
1089  call_site_prec = precondition_intra_to_inter (callee,
1090  caller_prec,
1091  seffects_callee);
1092  call_site_prec = transformer_normalize(call_site_prec, 2);
1093 
1094  /* translate_global_values(e_caller, call_site_prec); */
1097 
1098  /* Now deal with the callee */
1100  /* Set the htable with its variables because now we work
1101  in this frame */
1103 
1104  result = text_for_a_transformer(call_site_prec, false);
1105 
1111 
1112  return result;
1113 }
1114 
1115 /* Context to compute summary preconditions */
1116 
1119 
1124 static int number_of_call_sites = -1;
1125 
1127 {
1129 }
1130 
1132 {
1133  return number_of_call_sites;
1134 }
1135 
1136 /* Each time a statement is entered, its precondition is memorized*/
1138 {
1139  bool go_down = false;
1140  // FI: necessary for points-to, (potentially?) useful for warnings and errors
1142 
1144  /* There may be or not a precondition associated to
1145  * this statement, depending on an intermediate disk
1146  * storage. However, if the ordering of statement s
1147  * is undefined, statement s is not reachable and the
1148  * corresponding call site should be ignored, as well
1149  * as call sites in statements controlled by s
1150  */
1151  /* FI: probably a memory leak is started here */
1153  current_statement = s;
1154 
1155  pips_assert("current precondition is defined",
1157 
1158  go_down = true;
1159  }
1160  else {
1162  go_down = false;
1163  }
1164 
1165  if(go_down && declaration_statement_p(s)) {
1166  list dl = statement_declarations(s);
1170  }
1171 
1172  return go_down;
1173 }
1174 
1175 /* Update the current_summary_precondition, if necessary */
1177 {
1178 #define PROCESS_CALL_DEBUG_LEVEL 5
1179 
1180  transformer caller_prec = transformer_undefined;
1181  transformer call_site_prec = transformer_undefined;
1182 
1183  if(call_function(c) != current_callee) {
1184  return true;
1185  }
1186 
1187 
1189 
1192  "Begin for module %s with %d call sites with caller %s\n",
1196  "call site precondition %p:\n", current_precondition);
1197  /* p might not be printable; it may (should!) contain formal parameters
1198  of module m */
1201  "current summary precondition for callee %s, %p:\n",
1204  /* p might not be printable; it may (should!) contain formal parameters
1205  of module m */
1207  }
1208 
1209  /* add to call site preconditions the links to the callee formal params */
1210  caller_prec = new_add_formal_to_actual_bindings
1214  "call site precondition in caller %s with bindings %p:\n",
1216  caller_prec);
1217  /* caller_prec should not be printable; it should contain
1218  * formal parameters of module callee
1219  */
1220  dump_transformer(caller_prec);
1221  }
1222 
1223  if(constant_path_analyzed_p()) {
1224  caller_prec = substitute_stubs_in_transformer(caller_prec, c, current_statement, false);
1225  caller_prec = substitute_formal_array_elements_in_precondition(caller_prec, current_callee, call_arguments(c), caller_prec, NIL);
1226  }
1227 
1228  /* transform the preconditions to make sense for the callee */
1229  /* Beware: call_site_prec and caller_prec are synonymous */
1230  call_site_prec =
1232  caller_prec,
1234 
1237  "call site precondition with filtered actual parameters:\n");
1238  dump_transformer(call_site_prec);
1239  }
1240 
1241  translate_global_values(current_caller, call_site_prec);
1242 
1245  "new call site precondition in caller's frame:\n");
1246  dump_transformer(call_site_prec);
1247  }
1248 
1249  /* Provoque initialization with an undefined transformer... */
1250  /*pips_assert("process_call", !transformer_undefined_p(call_site_prec)); */
1251 
1253 
1254  /* convert global variables in the summary precondition in the
1255  * caller's frame as defined by value mappings (FI, 1 February 1994)
1256  */
1257 
1258  /* p is returned in the callee's frame; there is no need for a
1259  * translation; the caller's frame should always contain the
1260  * callee's frame by definition of effects;
1261  *
1262  * Unfortunately, I do not remember *why* I added this
1263  * translation; It was linked to a problem encountered with
1264  * transformer and "invisible" variables, i.e. global variables
1265  * which are indirectly changed by a procedure which does not see
1266  * them; such variables receive an arbitrary existing global name;
1267  * they may receive different names in different context, because
1268  * there is no canonical name; each time, summary_precondition and
1269  * summary_transformer are used, they must be converted in a
1270  * unique frame, which can only be the frame of the current
1271  * module. In other words, you have to be in the same environment
1272  * to be allowed to combine preconditions.
1273  *
1274  * FI, 9 February 1994
1275  *
1276  * This may be now useless...
1277  */
1282  "old module current summary precondition (%p) in current frame:\n",
1285  }
1286 
1288  /* the former precondition represents the entire space :
1289  * the new precondition must also represent the entire space
1290  * BC, november 1994.
1291  */
1292  transformer_free(call_site_prec);
1293  }
1294  else {
1295  transformer new_current_summary_precondition =
1297  pips_assert("A new transformer is allocated",
1298  current_summary_precondition != call_site_prec);
1299  new_current_summary_precondition =
1301  call_site_prec);
1303  current_summary_precondition = new_current_summary_precondition;
1304 
1305  }
1306  }
1307  else {
1308  /* the former precondition is undefined. The new precondition
1309  * is defined by the current call site precondition
1310  * BC, november 1994.
1311  */
1312  current_summary_precondition = call_site_prec;
1313  }
1314 
1317  "new current summary precondition for module %s in current frame, %p:\n",
1321  }
1322 
1323  /* FI: Let's put the summary_precondition in the callee's frame..
1324  * Well, it's an illusion because translate_global_values() is
1325  * not symmetrical. It only can import global values. The summary
1326  * precondition is left in the last caller's frame. It will
1327  * have to be translated in callee's frame when used.
1328  */
1329  /*
1330  translate_global_values(current_callee,
1331  current_summary_precondition);
1332  */
1333 
1334  return true;
1335 }
1336 
1337 #if 0
1338 /* Update the current_summary_precondition, if necessary, for call
1339  located in the dimension declarations. May be useless because of
1340  function below... */
1341 static bool process_statement_for_summary_precondition(statement s)
1342 {
1343  bool ret_p = true;
1344  pips_internal_error("Not implemented. Should not be called.");
1345  if(declaration_statement_p(s)) {
1346  /* Look for call sites in the declarations, but see functions below... */
1347  //list dl = statement_declarations(s);
1348  //ret_p = process_call_for_summary_precondition();
1349  }
1350  return ret_p;
1351 }
1352 #endif
1353 
1354 /* This function is called to deal with call sites located in
1355  initialization expressions carried by declarations. */
1357  transformer pre)
1358 {
1359  current_precondition = pre;
1360  gen_recurse(e,
1361  call_domain,
1362  (bool (*)(void *)) process_call_for_summary_precondition,
1363  gen_null);
1364 }
1365 
1366 /* Update precondition t for callee with preconditions of call sites
1367  to callee in caller. Call sites are found in the statement of
1368  caller, but also in its declarations. Return the updated
1369  precondition t.
1370 */
1372  entity caller,
1373  entity callee)
1374 {
1375  statement caller_statement = (statement) db_get_memory_resource
1376  (DBR_CODE, module_local_name(caller), true);
1377  /* summary effects for the callee */
1379 
1380  pips_assert("callee is the current module",
1382 
1383  entity old_entity = get_current_module_entity();
1384  statement old_statement = get_current_module_statement();
1385 
1388 
1389  set_current_module_entity(caller);
1390  set_current_module_statement(caller_statement);
1392  current_caller = caller;
1394 
1395  if(use_points_to_p())
1397  db_get_memory_resource(DBR_POINTS_TO,
1398  module_local_name(caller), true) );
1399 
1402  (DBR_CUMULATED_EFFECTS,
1403  module_local_name(caller), true));
1404 
1407  (DBR_PROPER_EFFECTS,
1408  module_local_name(caller), true));
1409 
1412  (DBR_PRECONDITIONS,
1413  module_local_name(caller),
1414  true) );
1415 
1416  module_to_value_mappings(caller);
1417 
1418  /* calls hidden in dimension declarations are not caught because
1419  entities are not traversed by gen_recurse(). */
1420  gen_multi_recurse(caller_statement,
1423  // FI: to be checked. Should be useless.
1424  //statement_domain, process_declaration_for_summary_precondition, gen_null,
1425  NULL);
1426 
1430  if(use_points_to_p())
1431  reset_pt_to_list();
1435  set_current_module_entity(old_entity);
1436  set_current_module_statement(old_statement);
1437 
1442 
1444  // Problem: the initializer pass does not notify pipsmake that the
1445  // module list, a.k.a. %ALL, has been changed.
1446  // I do not know how to fix pipsmake. Add a new exception to
1447  // restart the computation of the requested resource list? How can
1448  // we combine this one with the pips_user_error() exception?
1449  pips_user_error("No summary precondition for module \"%s\". The callgraph "
1450  "is probably broken because stubs have been generated."
1451  "Please (re)compute the call graph,"
1452  " e.g. display CALLGRAPH_FILE.\n",
1453  entity_name(caller));
1454  }
1455 
1456  /* This normalization seems pretty uneffective for fraer01.tpips */
1459 
1460  return t;
1461 }
1462 ␌
1463 /* With value passing, writes on formal parameters are not effective
1464  * interprocedurally unless an array is passed as parameter.
1465  *
1466  * All new values corresponding to formal arguments of f must be
1467  * projected out and removed from the arguments list.
1468  *
1469  * Performed by side-effect on tf.
1470 */
1472 {
1473  list al = transformer_arguments(tf); // argument list
1474  list mfl = NIL; // modified formal list
1475  list omfl = NIL; // modified formal list
1476  list tvl = NIL; // temporary value list
1477  list ctvl = NIL; // current pointer in tvl
1478 
1479  FOREACH(ENTITY, a, al) {
1480  storage s = entity_storage(a);
1481 
1482  if(storage_formal_p(s)) {
1483  formal fs = storage_formal(s);
1484  if(formal_function(fs)==f) {
1485  //value v = entity_initial(a);
1486  if(!location_entity_p(a)) {
1487  // We are not dealing with a location entity, such as an
1488  // element of a formal array, which may be written in spite
1489  // of the value passing scheme
1490  entity nav = entity_to_new_value(a);
1491  entity oav = entity_to_old_value(a);
1492  mfl = CONS(ENTITY, nav, mfl);
1493  omfl = CONS(ENTITY, oav, omfl);
1494  }
1495  }
1496  }
1497  }
1498 
1499  /* The old values cannot be renamed directly after projection,
1500  because the transformer projection opearator detects an
1501  inconsistency. */
1502 
1503  /* Rename old values as temporary values in the caller frame. */
1504  FOREACH(ENTITY, oav, omfl) {
1506 
1507  tvl = CONS(ENTITY, tv, tvl);
1508  tf = transformer_value_substitute(tf, oav, tv);
1509  }
1510 
1511  /* Updates the argument list after the projections */
1512  tf = transformer_projection(tf, mfl);
1513 
1514  /* Rename tmp values as new values in the caller frame. */
1515  tvl = gen_nreverse(tvl);
1516  ctvl = tvl;
1517  /* oav renamed oav1 because of FOREACH macro implementation */
1518  FOREACH(ENTITY, oav1, omfl) {
1519  entity tv = ENTITY(CAR(ctvl));
1520  entity v = value_to_variable(oav1);
1521  entity nav = entity_to_new_value(v);
1522 
1523  tf = transformer_value_substitute(tf, tv, nav);
1524  POP(ctvl);
1525  }
1526 
1527  gen_free_list(tvl);
1528 
1529  return tf;
1530 }
1531 
void free_transformer(transformer p)
Definition: ri.c:2616
bool transformer_defined_p(transformer p)
Definition: ri.c:2626
bool db_resource_p(const char *rname, const char *oname)
true if exists and in loaded or stored state.
Definition: database.c:524
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
static entity callee
Definition: alias_pairs.c:62
void free_arguments(cons *args)
Definition: arguments.c:218
bool entity_is_argument_p(entity e, cons *args)
Definition: arguments.c:150
cons * arguments_add_entity(cons *a, entity e)
Definition: arguments.c:85
void dump_arguments(cons *args)
entity_name is a macro, hence the code replication
Definition: arguments.c:69
cons * arguments_difference(cons *a1, cons *a2)
set difference: a1 - a2 ; similar to set intersection
Definition: arguments.c:233
int Value
bool base_contains_variable_p(Pbase b, Variable v)
bool base_contains_variable_p(Pbase b, Variable v): returns true if variable v is one of b's elements...
Definition: base.c:136
transformer transformer_dup(transformer t_in)
transformer package - basic routines
Definition: basic.c:49
bool transformer_identity_p(transformer t)
Check that t is an identity function.
Definition: basic.c:154
void transformer_free(transformer t)
Definition: basic.c:68
transformer transformer_identity()
Allocate an identity transformer.
Definition: basic.c:110
transformer transformer_empty()
Allocate an empty transformer.
Definition: basic.c:120
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
#define CONTRAINTE_UNDEFINED
Pcontrainte contrainte_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
bool use_points_to_p()
list load_summary_effects(entity e)
FI->FI, FI->BC: these two functions should be moved into effects-util or effects-simple.
void reset_proper_rw_effects(void)
void set_proper_rw_effects(statement_effects)
void set_cumulated_rw_effects(statement_effects)
void reset_cumulated_rw_effects(void)
bool location_entity_p(entity)
Definition: locations.c:349
void set_pt_to_list(statement_points_to)
void reset_pt_to_list(void)
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
list concrete_effects_entities_which_may_conflict_with_scalar_entity(list fx, entity e)
Definition: conflicts.c:1278
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
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
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
#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
#define MAPL(_map_list_cp, _code, _l)
Apply some code on the addresses of all the elements of a list.
Definition: newgen_list.h:203
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
#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 DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
Definition: pipsdbm-local.h:66
bool declaration_statement_p(statement)
Had to be optimized according to Beatrice Creusillet.
Definition: statement.c:224
#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 pips_user_error
Definition: misc-local.h:147
#define MODULE_SEP_STRING
Definition: naming-local.h:30
#define STATEMENT_ORDERING_UNDEFINED
mapping.h inclusion
Definition: newgen-local.h:35
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
#define same_string_p(s1, s2)
void * gen_find_tabulated(const char *, int)
Definition: tabulated.c:218
int tag
TAG.
Definition: newgen_types.h:92
struct cons * list
Definition: newgen_types.h:106
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
char * dump_value_name(entity e)
char * dump_value_name(e): used as functional argument because entity_name is a macro
Definition: io.c:128
#define print_effects(e)
Definition: print.c:334
#define dump_transformer(t)
Definition: print.c:355
string basic_to_string(basic)
Definition: type.c:87
#define module_language(e)
implemented as a macro to allow lhs
#define entity_constant_p(e)
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
bool local_entity_of_module_p(entity e, entity module)
This test shows that "e" has been declared in "module".
Definition: entity.c:1069
code entity_code(entity e)
Definition: entity.c:1098
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
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
const char * entity_module_name(entity e)
See comments about module_name().
Definition: entity.c:1092
expression find_ith_argument(list args, int n)
Definition: expression.c:1147
bool c_language_module_p(entity m)
Definition: module.c:447
bool fortran_language_module_p(entity m)
Definition: module.c:452
basic basic_of_expression(expression)
basic basic_of_expression(expression exp): Makes a basic of the same basic as the expression "exp".
Definition: type.c:1383
type ultimate_type(type)
Definition: type.c:3466
statement pop_statement_global_stack(void)
Definition: static.c:352
bool same_basic_p(basic, basic)
check if two basics are similar.
Definition: type.c:969
bool type_equal_p(type, type)
Definition: type.c:547
bool same_scalar_location_p(entity, entity)
FI: transferred from semantics (should be used for effect translation as well)
Definition: variable.c:1992
void push_statement_on_statement_global_stack(statement)
Definition: static.c:333
string type_to_string(const type)
type.c
Definition: type.c:51
#define formal_offset(x)
Definition: ri.h:1408
#define value_tag(x)
Definition: ri.h:3064
#define transformer_undefined
Definition: ri.h:2847
#define transformer_undefined_p(x)
Definition: ri.h:2848
#define storage_formal_p(x)
Definition: ri.h:2522
#define call_function(x)
Definition: ri.h:709
#define storage_tag(x)
Definition: ri.h:2515
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define syntax_call_p(x)
Definition: ri.h:2734
#define ram_undefined
Definition: ri.h:2221
#define statement_ordering(x)
Definition: ri.h:2454
#define basic_tag(x)
Definition: ri.h:613
#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_value_intrinsic
Definition: ri.h:3034
@ is_value_unknown
Definition: ri.h:3035
@ is_value_constant
Definition: ri.h:3033
@ is_value_code
Definition: ri.h:3031
@ is_value_symbolic
Definition: ri.h:3032
#define code_declarations(x)
Definition: ri.h:784
#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 storage_formal(x)
Definition: ri.h:2524
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define language_c_p(x)
Definition: ri.h:1594
#define entity_undefined
Definition: ri.h:2761
#define expression_undefined
Definition: ri.h:1223
#define entity_name(x)
Definition: ri.h:2790
#define transformer_relation(x)
Definition: ri.h:2873
#define transformer_arguments(x)
Definition: ri.h:2871
#define formal_function(x)
Definition: ri.h:1406
#define syntax_call(x)
Definition: ri.h:2736
#define statement_declarations(x)
Definition: ri.h:2460
#define storage_ram(x)
Definition: ri.h:2521
#define ram_function(x)
Definition: ri.h:2247
#define storage_rom_p(x)
Definition: ri.h:2525
struct _newgen_struct_transformer_ * transformer
Definition: ri.h:431
#define call_arguments(x)
Definition: ri.h:711
#define entity_type(x)
Definition: ri.h:2792
#define expression_syntax(x)
Definition: ri.h:1247
#define storage_return_p(x)
Definition: ri.h:2516
#define predicate_system(x)
Definition: ri.h:2069
#define entity_domain
newgen_syntax_domain_defined
Definition: ri.h:410
#define variable_basic(x)
Definition: ri.h:3120
#define statement_undefined
Definition: ri.h:2419
#define storage_undefined
Definition: ri.h:2476
#define entity_initial(x)
Definition: ri.h:2796
transformer propagate_preconditions_in_declarations(list dl, transformer pre, void(*process_initial_expression)(expression, transformer))
This function is mostly copied from declarations_to_transformer().
transformer any_user_call_site_to_transformer(entity f, list pc, transformer pre, list __attribute__((unused)) ef)
FI: the handling of varargs had to be modified for Semantics/va_arg.c.
transformer substitute_formal_array_elements_in_precondition(transformer tf, entity f, list pc, transformer pre, list ef)
struct Ssysteme * Psysteme
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
Pcontrainte eq
element du vecteur colonne du systeme donne par l'analyse
Definition: sc_gram.c:108
Psysteme sc_equation_add(Psysteme sc, Pcontrainte c)
The basis of the constraint system is updated.
Definition: sc_insert_eq.c:101
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
char * strdup()
Psysteme sc_safe_normalize(Psysteme ps)
Psysteme sc_safe_normalize(Psysteme ps) output : ps, normalized.
transformer any_expression_to_transformer(entity v, expression expr, transformer pre, bool is_internal)
A set of functions to compute the transformer associated to an expression evaluated in a given contex...
Definition: expression.c:4993
transformer precondition_intra_to_inter(entity callee, transformer pre, list le)
void translate_global_value(entity m, transformer tf, entity v)
Try to convert an value on a non-local variable into an value on a local variable using a guessed nam...
static transformer current_precondition
transformer update_precondition_with_call_site_preconditions(transformer t, entity caller, entity callee)
Update precondition t for callee with preconditions of call sites to callee in caller.
void expressions_to_summary_precondition(transformer pre, list le)
void expression_to_summary_precondition(transformer pre, expression e)
transformer new_add_formal_to_actual_bindings(call c, transformer pre, entity caller)
Take side effects into account:
static bool memorize_precondition_for_summary_precondition(statement s)
Each time a statement is entered, its precondition is memorized.
static bool process_call_for_summary_precondition(call c)
Update the current_summary_precondition, if necessary.
#define PROCESS_CALL_DEBUG_LEVEL
transformer get_module_precondition(entity m)
package semantics
void add_module_call_site_precondition(entity m, transformer p)
static entity current_caller
Context to compute summary preconditions.
void call_to_summary_precondition(transformer pre, call c)
static transformer current_summary_precondition
void update_summary_precondition_in_declaration(expression e, transformer pre)
This function is called to deal with call sites located in initialization expressions carried by decl...
static entity current_callee
bool same_analyzable_type_scalar_entity_list_p(list l)
#define DEBUG_PRECONDITION_INTRA_TO_INTER
static statement current_statement
transformer value_passing_summary_transformer(entity f, transformer tf)
With value passing, writes on formal parameters are not effective interprocedurally unless an array i...
int get_call_site_number()
void translate_global_values(entity m, transformer tf)
static list summary_effects_of_callee
void reset_call_site_number()
text call_site_to_module_precondition_text(entity caller, entity callee, statement s, call c)
This function does everything needed.
list module_to_formal_analyzable_parameters(entity f)
returns a module's parameter's list
static int number_of_call_sites
transformer add_formal_to_actual_bindings(call c, transformer pre, entity caller)
add_formal_to_actual_bindings(call c, transformer pre, entity caller):
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 substitute_stubs_in_transformer(transformer tf, call c, statement s, bool backward_p)
Exploit the binding map to substitute calles's stubs by actual arguments, which may be stubs of the c...
Definition: points_to.c:256
text text_for_a_transformer(transformer tran, bool is_a_transformer)
call this one from outside.
Definition: prettyprint.c:540
transformer load_statement_semantic(statement)
void set_semantic_map(statement_mapping)
void reset_semantic_map(void)
#define ifdebug(n)
Definition: sg.c:47
Pbase base
Definition: sc-local.h:75
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
struct Svecteur * succ
Definition: vecteur-local.h:92
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
#define OLD_VALUE_SUFFIX
transformer transformer_convex_hull(transformer t1, transformer t2)
transformer transformer_convex_hull(t1, t2): compute convex hull for t1 and t2; t1 and t2 are slightl...
Definition: convex_hull.c:216
transformer transformer_projection_with_redundancy_elimination(transformer t, list args, Psysteme(*elim)(Psysteme))
It is not clear if this function projects values or variables.
Definition: transformer.c:1322
transformer transformer_normalize(transformer t, int level)
Eliminate (some) rational or integer redundancy.
Definition: transformer.c:932
transformer transformer_filter(transformer t, list args)
transformer transformer_filter(transformer t, cons * args): projection of t along the hyperplane defi...
Definition: transformer.c:1716
bool transformer_empty_p(transformer t)
If true is returned, the transformer certainly is empty.
Definition: transformer.c:2455
transformer transformer_safe_image_intersection(transformer t1, transformer t2)
Allocate a new transformer.
Definition: transformer.c:647
transformer transformer_value_substitute(transformer t, entity e1, entity e2)
transformer transformer_value_substitute(transformer t, entity e1, entity e2): if e2 does not appear ...
Definition: transformer.c:1993
bool transformer_value_substitutable_p(transformer t, entity e1, entity e2)
If e1 does not appear in t, it is substitutable.
Definition: transformer.c:2033
transformer transformer_safe_value_substitute(transformer t, entity e1, entity e2)
Definition: transformer.c:2048
transformer transformer_apply(transformer tf, transformer pre)
transformer transformer_apply(transformer tf, transformer pre): apply transformer tf on precondition ...
Definition: transformer.c:1559
transformer transformer_range(transformer tf)
Return the range of relation tf in a newly allocated transformer.
Definition: transformer.c:714
transformer transformer_projection(transformer t, list args)
values in args must be in t's base
Definition: transformer.c:1267
entity make_local_temporary_value_entity(type)
Definition: value.c:605
entity global_new_value_to_global_old_value(entity)
Definition: value.c:716
bool value_entity_p(entity)
Definition: value.c:976
bool analyzable_scalar_entity_p(entity)
The entity type is one of the analyzed types.
Definition: value.c:471
entity external_entity_to_new_value(entity)
Definition: value.c:1411
entity value_alias(entity)
Static aliasing.
Definition: value.c:1729
bool global_old_value_p(entity)
Return true if an entity is a global old value (such as "i#init"...).
Definition: value.c:690
bool constant_path_analyzed_p(void)
Definition: value.c:330
entity entity_to_new_value(entity)
Definition: value.c:859
void free_value_mappings(void)
Normal call to free the mappings.
Definition: value.c:1212
entity entity_to_old_value(entity)
Definition: value.c:869
entity value_to_variable(entity)
Get the primitive variable associated to any value involved in a transformer.
Definition: value.c:1624
#define vecteur_var(v)
struct Svecteur * Pbase
#define base_rm(b)
void * Variable
arithmetique is a requirement for vecteur, but I do not want to inforce it in all pips files....
Definition: vecteur-local.h:60
#define BASE_UNDEFINED
Pvecteur vect_dup(Pvecteur v_in)
Pvecteur vect_dup(Pvecteur v_in): duplication du vecteur v_in; allocation de et copie dans v_out;.
Definition: alloc.c:51
Pvecteur vect_new(Variable var, Value coeff)
Pvecteur vect_new(Variable var,Value coeff): allocation d'un vecteur colineaire au vecteur de base va...
Definition: alloc.c:110
void vect_add_elem(Pvecteur *pvect, Variable var, Value val)
void vect_add_elem(Pvecteur * pvect, Variable var, Value val): addition d'un vecteur colineaire au ve...
Definition: unaires.c:72