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 generic effects : Be'atrice Creusillet 5/97
28  *
29  * File: interprocedural.c
30  * ~~~~~~~~~~~~~~~~~~~~~~~
31  *
32  * This File contains the generic functions necessary for the interprocedural
33  * computation of all types of in effects.
34  *
35  */
36 
37 #include <stdio.h>
38 #include <string.h>
39 
40 #include "genC.h"
41 #include "linear.h"
42 #include "ri.h"
43 #include "effects.h"
44 #include "text.h"
45 
46 #include "misc.h"
47 #include "text-util.h"
48 #include "ri-util.h"
49 #include "prettyprint.h"
50 #include "effects-util.h"
51 
52 #include "effects-generic.h"
53 
54 #include "semantics.h"
55 
56 #define min(a,b) (((a)<(b))?(a):(b))
57 #define max(a,b) (((a)>(b))?(a):(b))
58 
59 
60 extern string compilation_unit_of_module(const char *);
61 
62 /**************************************************** FORTRAN */
63 
64 /**
65 
66  This function translates the list of effects l_sum_eff summarizing the
67  effects of module callee from its name space to the name space of the
68  caller, that is to say the current module being analyzed.
69  It is generic, which means that it does not depend on the representation
70  of effects. There is another similar function for C modules.
71 
72  @param callee is the called module
73  @param real_args is the list of actual arguments
74  @param l_sum_eff is the list of summary effects for function func
75  @return a list of effects in the caller name space
76 
77  */
79  entity callee,
80  list /* of expression */ real_args,
81  list /* of effect */ l_sum_eff,
83 {
84  list le;
85  // functions that can be pointed by fortran_effects_backward_translation_op:
86  // simple_effects_backward_translation
87  // convex_regions_backward_translation
88  le = (*fortran_effects_backward_translation_op)(callee, real_args, l_sum_eff,
89  context);
90  return le;
91 
92 }
93 ␌
94 /************************************************************ C */
95 
96 static list
97 c_address_of_actual_argument_to_may_summary_effects(expression arg1,
98  tag act)
99 {
100  list l_res = NIL, l_tmp = NIL;
101 
102  pips_debug(5, "address_of case \n");
103  list l_real_arg_eff = NIL;
105  (arg1, &l_real_arg_eff, true);
106  effects_free(l_tmp);
107 
108  FOREACH(EFFECT, real_arg_eff, l_real_arg_eff) {
109  if (anywhere_effect_p(real_arg_eff)) {
110  pips_debug(6, "anywhere effects \n");
111  l_res = gen_nconc
112  (l_res,
113  effect_to_effects_with_given_tag(real_arg_eff, act));
114  }
115  else {
116  type eff_type = expression_to_type(arg1);
117  reference eff_ref = effect_any_reference(real_arg_eff);
118  list last_ind = gen_last(reference_indices(eff_ref));
119  if(!ENDP(last_ind)) {
120  /* The operand of & is subcripted */
121  /* the effect last index must be changed to '*' if it's
122  * not already the case and if it is not a structure or
123  * union field.
124  */
125  expression n_exp;
126  expression last_eff_ind = EXPRESSION(CAR(last_ind));
127  bool field_p = false;
128  /* first check if the last index is a structure field */
129  if (expression_reference_p(last_eff_ind)) {
130  field_p = entity_field_p(reference_variable(expression_reference(last_eff_ind)));
131  }
132  if(!field_p && !unbounded_expression_p(last_eff_ind)) {
133  n_exp = make_unbounded_expression();
134  // functions that can be pointed by effect_change_ith_dimension_expression_func:
135  // simple_effect_change_ith_dimension_expression
136  // convex_region_change_ith_dimension_expression
137  (*effect_change_ith_dimension_expression_func)
138  (real_arg_eff, n_exp,
139  gen_length(reference_indices(eff_ref)));
140  free_expression(n_exp);
141  }
142  }
143 
144  l_res = gen_nconc
145  (l_res,
147  (real_arg_eff,
148  eff_type,
149  act,
150  true,
151  10, /* to avoid too long paths until GAPS are handled */
152  false));
153  }
154  gen_free_list(l_real_arg_eff);
155  }
156  return l_res;
157 }
158 
159 /**
160 
161  @param real_arg the real argument expression
162  @param act is a tag to choose the action of the main effect :
163  'r' for read, 'w' for write, and 'x' for read and write.
164  @return a list of effects corresponding to the possible effects
165  the function could do on the actual argument
166 
167  */
169 {
170  list l_res = NIL, l_tmp;
171 
172  // type real_arg_t = expression_to_type(real_arg);
173  type real_arg_t = points_to_expression_to_concrete_type(real_arg);
174  int real_arg_t_d = effect_type_depth(real_arg_t);
176 
180  else
182 
183  pips_debug(6,"actual argument %s, with type %s, and type depth %d\n",
184  expression_to_string(real_arg),
185  type_to_string(real_arg_t), real_arg_t_d);
186 
187  if (real_arg_t_d == 0)
188  {
189  pips_debug(6, "actual argument is a constant expression -> NIL\n");
190  }
191  else
192  {
193  syntax s = expression_syntax(real_arg);
194 
195  switch(syntax_tag(s))
196  {
197  case is_syntax_call:
198  /*
199  * Two special call cases for :
200  * - the assignment
201  * - and the ADDRESS_OF operator to avoid
202  * losing to musch information because we don't know how to
203  * represent &p access path in the general case.
204  */
205  {
206  call real_call = syntax_call(s);
207  entity real_op = call_function(real_call);
208  list args = call_arguments(real_call);
209 
210  if (ENTITY_ASSIGN_P(real_op)) {
211  pips_debug(5, "assignment case \n");
213  (EXPRESSION(CAR(CDR(args))), act);
214  break;
215  }
216  else if(ENTITY_ADDRESS_OF_P(real_op)) {
217  expression arg1 = EXPRESSION(CAR(args));
218  l_res = c_address_of_actual_argument_to_may_summary_effects(arg1, act);
219  break;
220  }
221  }
222  // no break
224  case is_syntax_reference:
225  case is_syntax_subscript:
226  {
227  list l_real_arg_eff = NIL;
228  pips_debug(5, "general call, reference or subscript case \n");
230  (real_arg, &l_real_arg_eff, true);
231  effects_free(l_tmp);
232 
233  FOREACH(EFFECT, real_arg_eff, l_real_arg_eff)
234  {
235  if (anywhere_effect_p(real_arg_eff))
236  {
237  pips_debug(6, "anywhere effects \n");
238  l_res = gen_nconc
239  (l_res,
241  act));
242  }
243  else
244  {
245  /* l_res = gen_nconc
246  (l_res,
247  generic_effect_generate_all_accessible_paths_effects
248  (real_arg_eff, real_arg_t, act)); */
249  l_res = gen_nconc
251  real_arg_t,
252  act,
253  false,
254  10, /* to avoid too long paths until GAPS are handled */
255  false));
256  }
257  }
258  gen_free_list(l_real_arg_eff);
259  }
260  break;
261  case is_syntax_cast:
262  {
264  (cast_expression(syntax_cast(s)), act);
265  }
266  break;
268  {
269  /* generate no effects : this case should never appear because
270  * of the test if (real_arg_t_d == 0)
271  */
272  }
273  break;
274  case is_syntax_va_arg:
275  {
276  list al = syntax_va_arg(s);
279  (sizeofexpression_expression(ae), act);
280  break;
281  }
282  default:
283  pips_internal_error("case not handled");
284  break;
285  }
286 
287  } /* else du if (real_arg_t_d == 0) */
288 
289  // functions that can be pointed by effects_precondition_composition_op:
290  // effects_composition_with_preconditions_nop
291  // convex_regions_precondition_compose
293  (*effects_precondition_composition_op)(l_res, context, false);
294 
295  effects_to_may_effects(l_res);
296 
297  ifdebug(6)
298  {
299  pips_debug(6, "end, resulting effects are :\n");
300  (*effects_prettyprint_func)(l_res);
301  }
302  return(l_res);
303 }
304 ␌
305 /* remove the current element from the list */
306 static void remove_current_element_from_effect_list(list * l_begin, list *l_current, list l_prec)
307 {
308  if (*l_begin == *l_current)
309  {
310  *l_current = CDR(*l_current);
311  CDR(*l_begin) = NIL;
312  gen_free_list(*l_begin);
313  *l_begin = *l_current;
314  }
315  else
316  {
317  CDR(l_prec) = CDR(*l_current);
318  CDR(*l_current) = NIL;
319  gen_free_list(*l_current);
320  *l_current = CDR(l_prec);
321  }
322 }
323 
324 static void skip_current_element_from_effect_list(list *l_current, list * l_prec)
325 {
326  *l_prec = *l_current;
327  *l_current = CDR(*l_current);
328 }
329 
330 /**
331  This function translates the list of effects l_sum_eff summarizing
332  the effects of module callee from its name space to the name space of
333  the caller, that is to say the current module being analyzed. It is
334  generic, which means that it does not depend on the representation of
335  effects. There is another similar function for fortran modules.
336 
337  @param callee is the called module
338  @param real_args is the list of actual arguments
339  @param l_sum_eff is the list of summary effects for function func
340  @param the current precondition if available
341  @return a list of effects in the caller name space
342 
343 */
345  list /* of expression */ real_args,
346  list /* of effect */ l_sum_eff,
348 {
349  list l_begin = gen_copy_seq(l_sum_eff); /* effects are not copied */
350  list l_prec = NIL, l_current;
351  list l_eff = NIL; /* proper effect list to be returned */
352  list ra;
353  bool param_varargs_p = false;
355  functional f = type_functional(callee_ut);
356  list formal_args = functional_parameters(f);
357  int arg_num;
358 
359  ifdebug(2)
360  {
361  pips_debug(2, "begin for function %s\n", entity_local_name(callee));
362  pips_debug(2, "with actual arguments :\n");
363  print_expressions(real_args);
364  pips_debug(2, "and effects :\n");
365  (*effects_prettyprint_func)(l_sum_eff);
366  }
367 
368  // functions that can be pointed by effects_translation_init_func:
369  // simple_effects_translation_init
370  // convex_regions_translation_init
371  (*effects_translation_init_func)(callee, real_args, true);
372 
373  /* first, take care of global and formal context effects */
374 
376  l_current = l_begin;
377  l_prec = NIL;
378  while(!ENDP(l_current))
379  {
380  effect eff = EFFECT(CAR(l_current));
382  entity v = reference_variable(r);
383 
384  if(!formal_parameter_p(v))
385  {
386  /* This effect must be either a global effect or an effect
387  * on the global context if points-to information is used.
388  *
389  * A global effect does not require a translation in
390  * C. However, it may not be in the scope of the caller.
391  *
392  * A formal context effect must be translated.
393  *
394  * In both cases, the descriptor, when it exists, must be
395  * translated.
396  */
397  if(global_variable_p(v)) { // even if it also is a stub
398  effect n_eff = (*effect_dup_func)(eff);
399  (*effect_descriptor_interprocedural_translation_op)(n_eff);
400  l_eff = gen_nconc(l_eff, CONS(EFFECT, n_eff, NIL));
401  }
402  else if(entity_stub_sink_p(v)) {
403  list n_effects
405  FOREACH(EFFECT, n_effect, n_effects) {
406  // functions that can be pointed by effect_descriptor_interprocedural_translation_op:
407  // simple_effect_descriptor_interprocedural_translation
408  // convex_region_descriptor_translation
409  (*effect_descriptor_interprocedural_translation_op)(n_effect);
410  }
411  l_eff = gen_nconc(l_eff, n_effects);
412  }
413  else {
414  /* Heap and package effects are simply copied, no translation
415  required */
416  // extern string effect_to_string(effect); // in effects-simple and not effects-util
417  //pips_user_warning("Translation error for \"%s\".\n",
418  // effect_to_string(eff));
419  // functions that can be pointed by effect_dup_func:
420  // simple_effect_dup
421  // region_dup
422  // copy_effect
423  effect n_eff = (*effect_dup_func)(eff);
424  // functions that can be pointed by effect_descriptor_interprocedural_translation_op:
425  // simple_effect_descriptor_interprocedural_translation
426  // convex_region_descriptor_translation
427  (*effect_descriptor_interprocedural_translation_op)(n_eff);
428  l_eff = gen_nconc(l_eff,CONS(EFFECT, n_eff, NIL));
429  }
430 
431  remove_current_element_from_effect_list(&l_begin, &l_current, l_prec);
432  }
433  else {
434  skip_current_element_from_effect_list(&l_current, &l_prec);
435  }
436  } /* while */
437 
438  ifdebug(5)
439  {
440  pips_debug(5, "translated global effects :\n");
441  (*effects_prettyprint_func)(l_eff);
442  pips_debug(5, "remaining effects :\n");
443  (*effects_prettyprint_func)(l_begin);
444  }
445 
446  /* then, handle effects on formal parameters */
447 
448  for (ra = real_args, arg_num = 1; !ENDP(ra); ra = CDR(ra), arg_num++)
449  {
450  expression real_arg = EXPRESSION(CAR(ra));
451  parameter formal_arg;
452  type te;
453  bool spurious_real_arg_p = false;
454 
455  pips_debug(5, "current real arg : %s\n", expression_to_string(real_arg));
456 
457  if (!param_varargs_p)
458  {
459  if(ENDP(formal_args)) {
460  semantics_user_warning("Function \"%s\" is called with too many arguments in function \"%s\" \n",
463  spurious_real_arg_p = true;
464  }
465  else {
466  formal_arg = PARAMETER(CAR(formal_args));
467  te = parameter_type(formal_arg);
468  pips_debug(8, "parameter type : %s\n", type_to_string(te));
469  param_varargs_p = param_varargs_p || type_varargs_p(te);
470  }
471  }
472 
473  if (param_varargs_p)
474  {
475  pips_debug(5, "vararg case \n");
476  l_eff = gen_nconc(l_eff,
478  'x'));
479  }
480  else if (!spurious_real_arg_p)
481  {
482  list l_eff_on_current_formal = NIL;
483 
484  dummy formal_arg_dummy = parameter_dummy(formal_arg);
485  if (!dummy_unknown_p(formal_arg_dummy))
486  pips_debug(5, "corresponding formal argument :%s\n",
487  entity_name(dummy_identifier(formal_arg_dummy))
488  );
489  else
490  pips_debug(5, "unknown dummy\n");
491 
492  /* first build the list of effects on the current formal argument */
493  l_current = l_begin;
494  l_prec = NIL;
495  while(!ENDP(l_current))
496  {
497  effect eff = EFFECT(CAR(l_current));
498  reference eff_ref = effect_any_reference(eff);
499  entity eff_ent = reference_variable(eff_ref);
500 
501  if (ith_parameter_p(callee, eff_ent, arg_num))
502  {
503  bool exact_p = false;
504  /* Whatever the real_arg may be if there is an effect on
505  * the sole value of the formal arg, it generates no effect
506  * on the caller side.
507  */
508  if (ENDP(reference_indices(eff_ref))
509  ||
510  (!entity_array_p(eff_ent) // to work around the fact that formal arrays are not internally represented as pointers for the moment
511  && !effect_reference_dereferencing_p(eff_ref, &exact_p))) // for structs and unions
512  {
513  pips_debug(5, "effect on the value of the formal parameter -> skipped\n");
514  }
515  else
516  {
517  l_eff_on_current_formal = gen_nconc
518  (l_eff_on_current_formal, CONS(EFFECT,eff, NIL));
519  }
520  /* c_summary_effect_to_proper_effects(eff, real_arg));*/
521  remove_current_element_from_effect_list(&l_begin, &l_current, l_prec);
522  }
523  else {
524  skip_current_element_from_effect_list(&l_current, &l_prec);
525  }
526  } /* while */
527 
528  ifdebug(5)
529  {
530  pips_debug(5, "effects on current formal argument:\n");
531  (*effects_prettyprint_func)(l_eff_on_current_formal);
532  }
533 
534  /* Eliminate callee stubs in the predicate
535  *
536  * Should be included in
537  * c_effects_on_formal_parameter_backward_translation_func() but
538  * we have to cope with argument "binding".
539  */
540  if(!set_undefined_p(binding)) {
541  FOREACH(EFFECT, eff, l_eff_on_current_formal) {
542  // Function available in convex effects
545  eff = substitute_stubs_in_convex_array_region(eff, true, binding);
546  }
547  }
548  }
549 
550  /* then translate them if possible */
551  if (!ENDP( l_eff_on_current_formal))
552  {
553  type real_arg_t = expression_to_type(real_arg);
555  {
556  // functions that can be pointed by c_effects_on_formal_parameter_backward_translation_func:
557  // c_simple_effects_on_formal_parameter_backward_translation
558  // c_convex_effects_on_formal_parameter_backward_translation
559  l_eff = gen_nconc
560  (l_eff,
562  (l_eff_on_current_formal, real_arg, context));
563  }
564  else
565  {
566  // FI: some work needed to retrieve the formal parameter name...
567  semantics_user_warning("Type of actual parameter, \"%s\", "
568  "incompatible with type of formal parameter, "
569  "\"%s\", for precise interprocedural effect "
570  "translation.\n",
571  type_to_full_string_definition(real_arg_t),
573  bool read_p = false;
574  bool write_p = false;
575  FOREACH(EFFECT, eff, l_eff_on_current_formal)
576  {
577  write_p = write_p || effect_write_p(eff);
578  read_p = read_p || effect_read_p(eff);
579  }
580 
581  tag t = write_p ? (read_p ? 'x' : 'w') : 'r';
582  l_eff = gen_nconc(l_eff,
584  }
585  free_type(real_arg_t);
586  }
587 
588  POP(formal_args);
589  } /* else if (!spurious_real_arg_p) */
590 
591  /* add the proper effects on the real arg evaluation on any case */
593 
594  } /* for */
595 
596  if(!set_undefined_p(binding))
597  set_free(binding);
598 
599  /* removed because the parser adds arguments to the function (see ticket 452) */
600  /* /\* check if there are too few actual arguments *\/ */
601  /* if (!param_varargs_p && !ENDP(formal_args) && !type_void_p(parameter_type(PARAMETER(CAR(formal_args))))) */
602  /* { */
603  /* pips_user_error("Function \"%s\" is called with too few arguments in function \"%s\" \n", */
604  /* entity_user_name(callee), */
605  /* entity_user_name(get_current_module_entity())); */
606  /* } */
607 
608  pips_debug_effects(5, "effects before fields translation:\n", l_eff);
609  // pips_debug(8, "callee's name is %s, current module name %s\n", entity_name(callee), entity_name(get_current_module_entity()));
610 
611  // string callee_cu_name = compilation_unit_of_module(entity_local_name(callee));
612  // string current_cu_name = compilation_unit_of_module(entity_local_name(get_current_module_entity()));
613  // pips_debug(8, "callee cu name %s, current cu name %s\n", callee_cu_name, current_cu_name);
614 
618 
619 
620  // functions that can be pointed by effects_translation_end_func:
621  // simple_effects_translation_end
622  // convex_regions_translation_end
623  (*effects_translation_end_func)();
624 
625  ifdebug(5)
626  {
627  pips_debug(5, "resulting effects :\n");
628  (*effects_prettyprint_func)(l_eff);
629  }
630 
631  return (l_eff);
632 }
633 
635  entity callee, list real_args, list l_eff, transformer context)
636 {
637  //entity caller = get_current_module_entity();
638  int arg_num;
639  list l_formal = NIL;
640  list l_global = NIL;
641  list l_res = NIL;
642  list r_args = real_args;
643 
644  ifdebug(2)
645  {
646  pips_debug(2, "begin for function %s\n", entity_local_name(callee));
647  pips_debug(2, "with actual arguments :\n");
648  print_expressions(real_args);
649  pips_debug(2, "and effects :\n");
650  (*effects_prettyprint_func)(l_eff);
651  }
652 
653  // functions that can be pointed by effects_translation_init_func:
654  // simple_effects_translation_init
655  // convex_regions_translation_init
656  (*effects_translation_init_func)(callee, real_args, false);
657 
658  /* First, global effects : To be done
659  * There is a problem here, since global entities maybe used as
660  * actual arguments and at the same time as globals.
661  */
662  FOREACH(EFFECT, eff, l_eff)
663  {
665 
666  if(storage_ram_p(eff_s) &&
668  && !heap_area_p(ram_section(storage_ram(eff_s)))
669  && !stack_area_p(ram_section(storage_ram(eff_s))))
670  {
671  /* This effect must be a global effect. It does not require
672  * translation in C. However, it may not be in the scope of
673  * the caller. */
674  // functions that can be pointed by effect_dup_func:
675  // simple_effect_dup
676  // region_dup
677  // copy_effect
678  effect eff_tmp = (*effect_dup_func)(eff);
679  // functions that can be pointed by effect_descriptor_interprocedural_translation_op:
680  // simple_effect_descriptor_interprocedural_translation
681  // convex_region_descriptor_translation
682  (*effect_descriptor_interprocedural_translation_op)(eff_tmp);
683  l_global = gen_nconc(l_global, CONS(EFFECT, eff_tmp, NIL));
684  }
685 
686  }
687 
688  /* We should also take care of varargs */
689 
690  /* Then formal args */
691 
692  for (arg_num = 1; !ENDP(r_args); r_args = CDR(r_args), arg_num++)
693  {
694  expression real_exp = EXPRESSION(CAR(r_args));
695  entity formal_ent = find_ith_formal_parameter(callee, arg_num);
696 
697  // functions that can be pointed by c_effects_on_actual_parameter_forward_translation_func:
698  // c_simple_effects_on_actual_parameter_forward_translation
699  // c_convex_effects_on_actual_parameter_forward_translation
700  l_formal = gen_nconc
701  (l_formal,
703  (callee, real_exp, formal_ent, l_eff, context));
704  } /* for */
705 
706  pips_debug_effects(2,"Formal effects : \n", l_formal);
707 
708 
709  l_res = gen_nconc(l_global, l_formal);
710 
711  pips_debug_effects(2,"effects before, fields translation: \n",l_res);
715  pips_debug_effects(2,"Ending with effects : \n",l_res);
716  // functions that can be pointed by effects_translation_end_func:
717  // simple_effects_translation_end
718  // convex_regions_translation_end
719  (*effects_translation_end_func)();
720  return(l_res);
721 }
722 
723 
724 
725 
726 /************************************************************ INTERFACE */
727 
728 list /* of effect */
730  entity callee,
731  list /* of expression */ real_args,
732  list /* of effect */ l_sum_eff,
734 {
735  list el = list_undefined;
736 
737 
740  l_sum_eff, context);
741  else
743  l_sum_eff, context);
744 
745 
746  return el;
747 }
748 
749 
751  list real_args,
752  list l_eff,
754 {
755  list el = list_undefined;
756 
757 
759  // functions that can be pointed by fortran_effects_forward_translation_op:
760  // simple_effects_forward_translation
761  // convex_regions_forward_translation
762  el = (*fortran_effects_forward_translation_op)(callee, real_args,
763  l_eff, context);
764  else
766  l_eff, context);
767 
768  return el;
769 }
770 
771 static void effect_translate_fields(effect eff)
772 {
773  pips_debug_effect(8, "input effect\n", eff);
774  list l_indices = cell_indices(effect_cell(eff));
775 
776  if (!ENDP(l_indices))
777  {
778 
779  type current_type = entity_basic_concrete_type(effect_entity(eff));
780 
781 
782 
783  while(!ENDP(l_indices))
784  {
785  switch(type_tag(current_type))
786  {
787  case is_type_void:
788  case is_type_functional:
789  // not expected because there are no more indices
790  pips_internal_error("void or functional type not expected here, please report\n");
791  break;
792  case is_type_variable:
793  {
794  pips_debug(8, "variable case\n");
795  basic current_basic = variable_basic(type_variable(current_type));
796  list current_dims = variable_dimensions(type_variable(current_type));
797 
798  /* skip array dimensions */
799  pips_debug(8, "poping %d dimensions\n", (int) gen_length(current_dims) );
800  for(int i=0; i< (int) gen_length(current_dims) && !ENDP(l_indices); i++, POP(l_indices));
801 
802  if (!ENDP(l_indices))
803  {
804  switch(basic_tag(current_basic))
805  {
806  case is_basic_pointer:
807  pips_debug(8, "pointer case, poping one dimension\n");
808  POP(l_indices);
809  current_type = basic_pointer(current_basic);
810  break;
811  case is_basic_derived:
812  pips_debug(8, "derived case\n");
813  current_type = entity_basic_concrete_type(basic_derived(current_basic));
814  break;
815  case is_basic_typedef:
816  pips_debug(8, "typedef case\n");
817  current_type = entity_basic_concrete_type(basic_typedef(current_basic));
818  break;
819  default:
820  pips_internal_error("this kind of basic should not appear here\n");
821  }
822  }
823 
824  break;
825  }
826  case is_type_struct:
827  case is_type_union:
828  case is_type_enum:
829  pips_debug(8, "struct, union or enum case\n");
830  expression exp = EXPRESSION(CAR(l_indices));
831  pips_assert("current index must be a field entity",
835  entity exp_ent = reference_variable(exp_ref);
836  const char* exp_ent_name = entity_user_name(exp_ent);
837 
838  // search for matching field in current type
839  list l_current_fields = type_fields(current_type);
840  bool found = false;
841  entity current_field = entity_undefined;
842  while(!found && !ENDP(l_current_fields))
843  {
844  current_field = ENTITY(CAR(l_current_fields));
845  pips_debug(8, "current field: %s \n", entity_name(current_field));
846 
847  if (same_entity_p(exp_ent, current_field))
848  {
849  pips_debug(8, "same field entities\n");
850  found = true;
851  }
852  else if (same_string_p(entity_user_name(current_field), exp_ent_name))
853  {
854  pips_debug(8, "matching field \n");
855  found = true;
856  }
857  POP(l_current_fields);
858  }
859  if (found)
860  {
861  reference_variable(exp_ref) = current_field;
862  current_type = entity_basic_concrete_type(current_field);
863  POP(l_indices);
864  }
865  else
866  pips_internal_error("matching field not found\n");
867  break;
868  default:
869  pips_internal_error("unexpected type: %s\n", type_to_string(current_type) );
870  break;
871  }
872  }
873  }
874 }
875 
876 void effects_translate_fields_compilation_unit(list l_eff, string source_cu_name, string target_cu_name)
877 {
878 
879  pips_debug(8, "source name: %s, target name %s\n",
880  source_cu_name, target_cu_name);
881  // if(false)
882  if (same_string_p(source_cu_name, target_cu_name))
883  {
884  pips_debug(8, "same compilation units \n");
885  }
886  else
887  {
888  FOREACH(EFFECT, eff, l_eff)
889  {
890  effect_translate_fields(eff);
891  }
892  }
893 }
void free_expression(expression p)
Definition: ri.c:853
void free_type(type p)
Definition: ri.c:2658
static entity callee
Definition: alias_pairs.c:62
bool entity_stub_sink_p(entity e)
test if an entity is a stub sink for a formal parameter e.g.
void const char const char const int
string compilation_unit_of_module(const char *)
The output is undefined if the module is referenced but not defined in the workspace,...
Definition: module.c:350
int dummy
A dummy file, to prevent empty libraries from breaking builds.
Definition: dummy.c:41
effect substitute_stubs_in_convex_array_region(effect, bool, set)
#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)
bool effects_private_current_context_empty_p(void)
void effects_to_may_effects(list)
transformer effects_private_current_context_head(void)
list generic_c_effects_forward_translation(entity, list, list, transformer)
list(* c_effects_on_formal_parameter_backward_translation_func)(list, expression, transformer)
list generic_effects_forward_translation(entity, list, list, transformer)
list generic_fortran_effects_backward_translation(entity, list, list, transformer)
interprocedural.c
void effects_free(list)
list generic_effects_backward_translation(entity, list, list, transformer)
bool effects_private_current_context_stack_initialized_p(void)
list generic_proper_effects_of_c_function_call_argument(expression)
list effect_to_effects_with_given_tag(effect, tag)
list backward_translation_of_points_to_formal_context_effect(entity, list, effect, set)
list generic_c_effects_backward_translation(entity, list, list, transformer)
list c_actual_argument_to_may_summary_effects(expression, tag)
list generic_effect_generate_all_accessible_paths_effects_with_level(effect, type, tag, bool, int, bool)
set safe_user_call_to_points_to_interprocedural_binding_set(entity, list)
void effects_translate_fields_compilation_unit(list, string, string)
list(* c_effects_on_actual_parameter_forward_translation_func)(entity, expression, entity, list, transformer)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define effect_write_p(eff)
#define effect_read_p(eff)
#define effect_scalar_p(eff) entity_scalar_p(effect_entity(eff))
list cell_indices(cell)
Definition: effects.c:64
bool effect_reference_dereferencing_p(reference, bool *)
Definition: type.c:233
entity effect_entity(effect)
cproto-generated files
Definition: effects.c:52
type points_to_expression_to_concrete_type(expression)
The type returned is stored in a hash-table.
Definition: type.c:617
bool anywhere_effect_p(effect)
Is it an anywhere effect? ANYMMODULE:ANYWHERE
Definition: effects.c:346
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 descriptor_convex_p(x)
Definition: effects.h:599
#define effect_descriptor(x)
Definition: effects.h:646
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
#define effect_cell(x)
Definition: effects.h:640
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
size_t gen_length(const list l)
Definition: list.c:150
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
list gen_last(list l)
Return the last element of a list.
Definition: list.c:578
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define list_undefined
Undefined list definition :-)
Definition: newgen_list.h:69
#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_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 same_string_p(s1, s2)
void set_free(set)
Definition: set.c:332
#define set_undefined_p(s)
Definition: newgen_set.h:49
int tag
TAG.
Definition: newgen_types.h:92
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
void print_expressions(list le)
Definition: expression.c:98
string expression_to_string(expression e)
Definition: expression.c:77
string type_to_full_string_definition(type)
type.c
Definition: type.c:45
#define ENTITY_ASSIGN_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
const char * entity_user_name(entity e)
Since entity_local_name may contain PIPS special characters such as prefixes (label,...
Definition: entity.c:487
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
bool entity_array_p(entity e)
Is e a variable with an array type?
Definition: entity.c:754
bool same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
bool entity_field_p(entity e)
e is the field of a structure
Definition: entity.c:857
bool parameter_passing_by_reference_p(entity f)
Definition: entity.c:2121
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
expression make_unbounded_expression()
Definition: expression.c:4339
bool expression_reference_p(expression e)
Test if an expression is a reference.
Definition: expression.c:528
bool unbounded_expression_p(expression e)
Definition: expression.c:4329
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
int effect_type_depth(type)
Number of steps to access the lowest leave of type t.
Definition: type.c:4948
type expression_to_type(expression)
For an array declared as int a[10][20], the type returned for a[i] is int [20].
Definition: type.c:2486
bool global_variable_p(entity)
Is v a global variable such as "int i;".
Definition: variable.c:1510
list type_fields(type)
Definition: type.c:3073
type entity_basic_concrete_type(entity)
retrieves or computes and then returns the basic concrete type of an entity
Definition: type.c:3677
bool formal_parameter_p(entity)
Definition: variable.c:1489
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 dummy_identifier(x)
Definition: ri.h:1033
@ is_basic_derived
Definition: ri.h:579
@ is_basic_pointer
Definition: ri.h:578
@ is_basic_typedef
Definition: ri.h:580
#define basic_pointer(x)
Definition: ri.h:637
#define transformer_undefined
Definition: ri.h:2847
#define transformer_undefined_p(x)
Definition: ri.h:2848
#define parameter_dummy(x)
Definition: ri.h:1823
#define parameter_type(x)
Definition: ri.h:1819
#define syntax_tag(x)
Definition: ri.h:2727
#define call_function(x)
Definition: ri.h:709
#define reference_variable(x)
Definition: ri.h:2326
#define basic_derived(x)
Definition: ri.h:640
#define SIZEOFEXPRESSION(x)
SIZEOFEXPRESSION.
Definition: ri.h:2364
#define type_tag(x)
Definition: ri.h:2940
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define sizeofexpression_expression(x)
Definition: ri.h:2409
#define syntax_cast(x)
Definition: ri.h:2739
#define type_functional(x)
Definition: ri.h:2952
#define syntax_va_arg(x)
Definition: ri.h:2751
#define basic_tag(x)
Definition: ri.h:613
#define type_variable(x)
Definition: ri.h:2949
#define entity_storage(x)
Definition: ri.h:2794
@ 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 ram_section(x)
Definition: ri.h:2249
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define cast_expression(x)
Definition: ri.h:747
#define basic_typedef(x)
Definition: ri.h:643
#define dummy_unknown_p(x)
Definition: ri.h:1028
#define entity_undefined
Definition: ri.h:2761
#define entity_name(x)
Definition: ri.h:2790
#define functional_parameters(x)
Definition: ri.h:1442
#define PARAMETER(x)
PARAMETER.
Definition: ri.h:1788
#define reference_indices(x)
Definition: ri.h:2328
#define syntax_call(x)
Definition: ri.h:2736
#define type_varargs_p(x)
Definition: ri.h:2953
#define variable_dimensions(x)
Definition: ri.h:3122
#define storage_ram(x)
Definition: ri.h:2521
#define call_arguments(x)
Definition: ri.h:711
@ is_type_void
Definition: ri.h:2904
@ is_type_enum
Definition: ri.h:2907
@ is_type_functional
Definition: ri.h:2901
@ is_type_variable
Definition: ri.h:2900
@ is_type_union
Definition: ri.h:2906
@ is_type_struct
Definition: ri.h:2905
#define expression_syntax(x)
Definition: ri.h:1247
#define variable_basic(x)
Definition: ri.h:3120
#define semantics_user_warning
#define ifdebug(n)
Definition: sg.c:47
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
Definition: delay.c:253
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207