PIPS
rw_effects_engine.c
Go to the documentation of this file.
1 /*
2 
3  $Id: rw_effects_engine.c 23495 2018-10-24 09:19:47Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27 /* package generic effects : Be'atrice Creusillet 5/97
28  *
29  * File: rw_effects_engine.c
30  * ~~~~~~~~~~~~~~~~~~~~~~~~~
31  *
32  * This File contains the generic functions necessary for the computation of
33  * all types of read and write effects and cumulated references.
34  */
35 #include <stdio.h>
36 #include <string.h>
37 
38 #include "genC.h"
39 
40 #include "linear.h"
41 
42 #include "misc.h"
43 
44 #include "text.h"
45 #include "ri.h"
46 #include "effects.h"
47 
48 #include "ri-util.h"
49 #include "prettyprint.h"
50 #include "effects-util.h"
51 #include "text-util.h"
52 
53 #include "properties.h"
54 
55 #include "pipsdbm.h"
56 
57 #include "effects-generic.h"
58 
59 #include "pointer_values.h"
60 
61 /************************************************ TO CONTRACT PROPER EFFECTS */
62 
63 static bool contract_p = true;
64 
65 void set_contracted_rw_effects(bool b)
66 {
67  contract_p = b;
68 }
69 
70 
71 /*********************************************** INTERPROCEDURAL COMPUTATION */
72 
73 bool summary_rw_effects_engine(const char* module_name)
74 {
75  list l_glob = NIL, l_loc = NIL,l_loc2 = NIL, l_dec=NIL;
76  statement module_stat;
77 
80  db_get_memory_resource(DBR_CODE, module_name, true) );
81  module_stat = get_current_module_statement();
83  make_statement_global_stack(); // for calls to semantics libray
84 
85  // functions that can be pointed by effects_computation_init_func:
86  // effects_computation_no_init
87  // init_convex_in_out_regions
88  // init_convex_rw_regions
89  (*effects_computation_init_func)(module_name);
90 
91  debug_on("SUMMARY_EFFECTS_DEBUG_LEVEL");
92 
94 
95  if(empty_statement_p(module_stat)) {
96  if(get_bool_property("MAXIMAL_EFFECTS_FOR_UNKNOWN_FUNCTIONS")) {
98  }
99  else if(get_bool_property("MAXIMAL_PARAMETER_EFFECTS_FOR_UNKNOWN_FUNCTIONS")) {
100  // Generate all possible paths from the parameters
101  // with read and write actions
102  // I guess this does not work with varargs...
103  // This may not be sufficient when there are pointers
104  // In this case, we should use points_to
105  // dummy targets to generate effects from them
106  // but only for paths from formal arguments with pointer basic
107  // BC.
108  //entity m = get_current_module_entity();
109  //type m_utype = ultimate_type(entity_type(m));
111  // Types of formal parameters, not the formal parameters themselves
112  //list l_formals = functional_parameters(type_functional(m_utype));
113 
114  FOREACH(ENTITY, formal, l_formals)
115  {
117  list l_tmp = NIL;
118 
119  if (!ENDP(variable_dimensions(type_variable(formal_t))))
120  {
121  // functions that can be pointed by reference_to_effect_func:
122  // reference_to_simple_effect
123  // reference_to_convex_region
124  // reference_to_reference_effect
125  effect eff = (*reference_to_effect_func)
128  (eff, formal_t, 'x');
129  // free the dummy effect
130  // functions that can be pointed by effect_free_func:
131  // free_effect
132  // region_free
133  (*effect_free_func)(eff);
134  }
135  l_loc = gen_nconc(l_tmp, l_loc);
136  }
137  }
138  }
139 
140  // l_loc may still be equal to NIL even if module_stat is an empty statement
141  // and if the previously tested properties are true, because
142  // the module may have no formal argument at all. BC.
143  if(ENDP(l_loc) && !empty_statement_p(module_stat)) {
144  l_loc = load_rw_effects_list(module_stat);
145  ifdebug(2){
146  pips_debug(2, "local regions, before translation to global scope:\n");
147  (*effects_prettyprint_func)(l_loc);
148  }
149  }
150 
152  ifdebug(8) {
153  int nb_param;
154  pips_debug(8, "Summary effects from declarations:\n");
155  (*effects_prettyprint_func)(l_dec);
157  pips_debug(8, "number of declared formal parameters:%d\n", nb_param);
158 
159  }
160 
161  l_loc2 = gen_append(l_loc,l_dec);
162 
163  // MAP(EFFECT, e, fprintf(stderr, "=%s=", entity_name(reference_variable(effect_any_reference(e)))) ,l_loc2);
164  // functions that can be pointed by effects_local_to_global_translation_op:
165  // effects_dynamic_elim
166  // regions_dynamic_elim
167  l_glob = (*effects_local_to_global_translation_op)(l_loc2);
168 
169  ifdebug(4)
170  {
171  /* Check that summary effects are not corrupted */
173  pips_internal_error("SDFI effects for \"%s\" are corrupted ",
175  }
176 
177  /* Different effects may have been reduced to the same one */
178  /* FI: I'm not to sure the parameter true is generic */
179  l_glob = proper_effects_combine(l_glob, true);
180 
181  ifdebug(2){
182  pips_debug(2, "local regions, after translation to global scope:\n");
183  (*effects_prettyprint_func)(l_loc2);
184  pips_debug(2, "global regions, after translation to global scope:\n");
185  (*effects_prettyprint_func)(l_glob);
186  }
187 
188  ifdebug(4)
189  {
190  /* Check that summary effects are not corrupted */
192  pips_internal_error("SDFI effects for \"%s\" are corrupted",
194  }
195 
196  (*db_put_summary_rw_effects_func)(module_name, l_glob);
197 
199  free_statement_global_stack(); // for calls to semantics libray
200 
204 
205  debug_off();
206  // functions that can be pointed by effects_computation_reset_func:
207  // effects_computation_no_reset
208  // reset_convex_in_out_regions
209  // reset_convex_rw_regions
210  (*effects_computation_reset_func)(module_name);
211 
212  return(true);
213 }
214 
215 /*********************************************** INTRAPROCEDURAL COMPUTATION */
216 
217 static void rw_effects_of_unstructured(unstructured unst)
218 {
220  list blocs = NIL ;
221  list le = NIL ;
222  control ct;
223 
224  pips_debug(2, "begin\n");
225 
226  ct = unstructured_control(unst);
227 
228  if(control_predecessors(ct) == NIL && control_successors(ct) == NIL)
229  {
230  /* there is only one statement in u; no need for a fixed point */
231  pips_debug(3, "unique node\n");
233  }
234  else
235  {
236  transformer t_unst = (*load_transformer_func)(current_stat);
237  list l_node;
238 
239  CONTROL_MAP(c,
240  {
242  // functions that can be pointed by effects_test_union_op:
243  // EffectsMayUnion
244  // RegionsMayUnion
245  // ReferenceTestUnion
246  le = (*effects_test_union_op) (l_node, le, effects_same_action_p) ;
247  },
248  ct, blocs) ;
249  // functions that can be pointed by effects_transformer_composition_op:
250  // effects_composition_with_transformer_nop
251  // effects_undefined_composition_with_transformer
252  // convex_regions_transformer_compose
253  // simple_effects_composition_with_effect_transformer
254  le = (*effects_transformer_composition_op)(le, t_unst);
256  gen_free_list(blocs) ;
257  }
258 
259  // functions that can be pointed by effects_descriptor_normalize_func:
260  // simple_effects_descriptor_normalize
261  // convex_effects_descriptor_normalize
262  (*effects_descriptor_normalize_func)(le);
263 
264  ifdebug(2){
265  pips_debug(2, "R/W effects: \n");
266  (*effects_prettyprint_func)(le);
267  }
268  store_rw_effects_list(current_stat, le);
269 
270  pips_debug(2, "end\n");
271 }
272 
273 /*
274  * From BC's PhD:
275  *
276  * R[while(C)S] = R[C] U ( R[S] o E[C] ) U ( R[while(C)S] o T[S] o E[C] )
277  *
278  * However we do not have the lpf available to solve the recursive equation...
279  * Ok, let's try something else, with a few transformations:
280  *
281  * R[while(C)S] = Rc[while(C)S] u Rs[while(C)S] ;
282  *
283  * Rc[while(C)S] = R[C] u R[C] o T[S] o E[C] u ...
284  * = U_i=0^inf R[C] o (T[S] o E[C])^i
285  * = R[C] O U_i=0^inf (T[S] o E[C])^i
286  * = R[C] O T*[while(C)S] ;
287  *
288  * Rs[while(C)S] = R[S] o E[C] u R[S] o E[C] o T[S] o E[C] u ...
289  * = U_i=0^inf R[S] o E[C] o (T[S] o E[C])^i
290  * = R[S] o E[C] O U_i=0^inf (T[S] o E[C])^i
291  * = R[S] o E[C] O T*[while(C)S] ;
292  *
293  * Thus
294  *
295  * R[while(C)S] = (R[C] u R[S] o E[C]) O T*[while(C)S] ;
296  *
297  *
298  * I assume that someone (FI) is to provide:
299  *
300  * T*[while(C)S] = U_i=0^inf (T[S] o E[C])^i ;
301  *
302  * Note that T* can be computed as a fixpoint from the recursice equation:
303  *
304  * T*[while(C)S] = T*[while(C)S] o T[S] o E[C] u Id
305  *
306  * That is the resolution of the fixpoint for R is expressed as a fixpoint
307  * on transformers only, and a direct computation on R.
308  *
309  * Also we know that the output state is the one which makes C false.
310  *
311  * T[while(C)S] = E[.not.C] O T*[while(C)S] ;
312  *
313  * note that T[] Sigma -> Sigma,
314  * but T*[] Sigma -> P(Sigma)
315  * that is it describes exactly intermediate stores reached by the while.
316  *
317  * FC, 04/06/1998
318  */
319 static void rw_effects_of_while(whileloop w)
320 {
322  list l_prop, l_body, l_cond_first, l_res;
323  statement b = whileloop_body(w);
324  transformer trans;
325 
326  /* we should check if the loop is executed at least once :
327  * we could keep exact effects on scalars at least.
328  */
329 
330  l_prop = effects_dup(load_proper_rw_effects_list(current_stat)); /* R[C] */
331  if (contract_p)
332  l_prop = proper_to_summary_effects(l_prop);
333 
334  /* The condition is executed at least once : let's keep exact effects if we can */
335  l_cond_first = effects_dup(l_prop);
336 
337  l_body = effects_dup(load_rw_effects_list(b)); /* R[S] */
338  /* I use the famous over-approximation of E[C]: Id */
339  trans = (*load_transformer_func)(current_stat); /* T*[while(C)S] */
340 
341  // functions that can be pointed by effects_union_op:
342  // ProperEffectsMustUnion
343  // RegionsMustUnion
344  // ReferenceUnion
345  // EffectsMustUnion
346  l_body = (*effects_union_op)(l_body, l_prop, effects_same_action_p);
347  // functions that can be pointed by effects_transformer_composition_op:
348  // effects_composition_with_transformer_nop
349  // effects_undefined_composition_with_transformer
350  // convex_regions_transformer_compose
351  // simple_effects_composition_with_effect_transformer
352  l_body = (*effects_transformer_composition_op)(l_body, trans);
353 
354  /* We don't know whether the loop is executed at least once or not. */
355  effects_to_may_effects(l_body);
356 
357  /* We add the effects of the first condition evaluation */
358  // functions that can be pointed by effects_union_op:
359  // ProperEffectsMustUnion
360  // RegionsMustUnion
361  // ReferenceUnion
362  // EffectsMustUnion
363  l_res = (*effects_union_op)(l_cond_first, l_body, effects_same_action_p);
364 
365  // functions that can be pointed by effects_descriptor_normalize_func:
366  // simple_effects_descriptor_normalize
367  // convex_effects_descriptor_normalize
368  (*effects_descriptor_normalize_func)(l_res);
369 
370  store_rw_effects_list(current_stat, l_res);
371 }
372 
373 static void rw_effects_of_forloop(forloop w)
374 {
376  statement b = forloop_body(w);
377  transformer trans;
378 
379  list l_body = NIL, l_res = NIL, li = NIL, lc = NIL, linc = NIL, l_init = NIL, l_cond_inc = NIL;
380 
381  /* we should check if the loop is executed at least once :
382  * we could keep exact effects on scalars at least.
383  */
384 
385  /* proper_effects first : we must recompute them
386  * there are must effects for the intialization and the first evaluation
387  * of the condition.
388  * the next evaluations of the condition and the incrementation must be
389  * composed by the transformer.
390  */
391 
392  /* effects of initialization */
394 
395  /* effects of condition expression */
397 
398  /* effects of incrementation expression */
400  if (contract_p)
401  {
402  li = proper_to_summary_effects(li);
403  lc = proper_to_summary_effects(lc);
404  linc = proper_to_summary_effects(linc);
405  }
406  l_init = gen_nconc(li, lc);
407  // functions that can be pointed by effects_union_op:
408  // ProperEffectsMustUnion
409  // RegionsMustUnion
410  // ReferenceUnion
411  // EffectsMustUnion
412  l_cond_inc = (*effects_union_op)(effects_dup(lc), linc, effects_same_action_p);
413 
414  if (get_constant_paths_p())
415  {
416  list l_tmp = l_init;
418  effects_free(l_tmp);
419  l_tmp = l_cond_inc;
420  l_cond_inc = pointer_effects_to_constant_path_effects(l_cond_inc);
421  effects_free(l_tmp);
422  }
423 
424  l_body = effects_dup(load_rw_effects_list(b)); /* R[S] */
425  /* I use the famous over-approximation of E[C]: Id */
426  trans = (*load_transformer_func)(current_stat); /* T*[while(C)S] */
427 
428  // functions that can be pointed by effects_union_op:
429  // ProperEffectsMustUnion
430  // RegionsMustUnion
431  // ReferenceUnion
432  // EffectsMustUnion
433  l_body = (*effects_union_op)(l_body, l_cond_inc, effects_same_action_p);
434  // functions that can be pointed by effects_transformer_composition_op:
435  // effects_composition_with_transformer_nop
436  // effects_undefined_composition_with_transformer
437  // convex_regions_transformer_compose
438  // simple_effects_composition_with_effect_transformer
439  l_res = (*effects_transformer_composition_op)(l_body, trans);
440 
441  /* We don't know whether the loop is executed at least once or not. */
442  effects_to_may_effects(l_res);
443 
444  /* We finally add the effects of the initialization phase */
445  // functions that can be pointed by effects_union_op:
446  // ProperEffectsMustUnion
447  // RegionsMustUnion
448  // ReferenceUnion
449  // EffectsMustUnion
450  l_res = (*effects_union_op)(l_init, l_res, effects_same_action_p);
451 
452  // functions that can be pointed by effects_descriptor_normalize_func:
453  // simple_effects_descriptor_normalize
454  // convex_effects_descriptor_normalize
455  (*effects_descriptor_normalize_func)(l_res);
456 
457  store_rw_effects_list(current_stat, l_res);
458 }
459 
460 static void rw_effects_of_loop(loop l)
461 {
463  list l_prop, l_body, l_loop = NIL;
464  statement b = loop_body(l);
465  entity i = loop_index(l);
466  range r = loop_range(l);
467  transformer loop_trans;
468 
469  pips_debug(2, "begin\n");
470 
471  /* proper effects of loop */
472  l_prop = effects_dup(load_proper_rw_effects_list(current_stat));
473  if (contract_p)
474  l_prop = proper_to_summary_effects(l_prop);
475 
476  /* rw effects of loop body */
477  l_body = load_rw_effects_list(b);
478 
479  ifdebug(4){
480  pips_debug(4, "rw effects of loop body:\n");
481  (*effects_prettyprint_func)(l_body);
482  }
483  /* Loop body must not have a write effect on the loop index */
484  FOREACH(EFFECT, ef, l_body) {
485  if(effect_entity(ef)==i && action_write_p(effect_action(ef)))
486  pips_user_error("Index %s of loop %s defined in loop body. "
487  "Fortran 77 standard violation, see Section 11.10.5.\n",
490  }
491 
492  /* SG: effects on locals are masked if the loop is parallel */
493  if(loop_parallel_p(l)) {
496  gen_free_list(tmp);
497  }
498  else
499  l_body = effects_dup(l_body);
500 
501  /* COMPUTATION OF INVARIANT RW EFFECTS */
502 
503  /* We get the loop transformer, which gives the loop invariant */
504  /* We must remove the loop index from the list of modified variables */
505  loop_trans = (*load_transformer_func)(current_stat);
506 
507  ifdebug(8)
508  {
509  pips_debug(8, "loop transformer : \n");
510  // dump_transformer(loop_trans);
511  }
512 
513  loop_trans = transformer_remove_variable_and_dup(loop_trans, i);
514 
515  ifdebug(8)
516  {
517  pips_debug(8, "loop transformer after removing loop index %s : \n",
518  entity_name(i));
519  // dump_transformer(loop_trans);
520  }
521 
522 
523  /* And we compute the invariant RW effects. */
524  // functions that can be pointed by effects_transformer_composition_op:
525  // effects_composition_with_transformer_nop
526  // effects_undefined_composition_with_transformer
527  // convex_regions_transformer_compose
528  // simple_effects_composition_with_effect_transformer
529  l_body = (*effects_transformer_composition_op)(l_body, loop_trans);
531 
532  ifdebug(4){
533  pips_debug(4, "invariant rw effects of loop body:\n");
534  (*effects_prettyprint_func)(l_body);
535  }
536 
537  /* COMPUTATION OF RW EFFECTS OF LOOP FROM INVARIANT RW EFFECTS */
538  if (!ENDP(l_body))
539  {
540  l_loop = l_body;
541  /* We eliminate the loop index */
542  // functions that can be pointed by effects_union_over_range_op:
543  // effects_union_over_range_nop
544  // simple_effects_union_over_range
545  // convex_regions_union_over_range
546  l_loop = (*effects_union_over_range_op)(l_loop, i, r,
548  }
549 
550  ifdebug(4){
551  pips_debug(4, "rw effects of loop before adding proper effects:\n");
552  (*effects_prettyprint_func)(l_loop);
553  }
554 
555  /* We finally add the loop proper effects */
556  // functions that can be pointed by effects_union_op:
557  // ProperEffectsMustUnion
558  // RegionsMustUnion
559  // ReferenceUnion
560  // EffectsMustUnion
561  l_loop = (*effects_union_op)(l_loop, l_prop, effects_same_action_p);
562 
563  ifdebug(4){
564  pips_debug(4, "rw effects of loop after adding proper effects:\n");
565  (*effects_prettyprint_func)(l_loop);
566  }
567  // functions that can be pointed by effects_descriptor_normalize_func:
568  // simple_effects_descriptor_normalize
569  // convex_effects_descriptor_normalize
570  (*effects_descriptor_normalize_func)(l_loop);
571 
572  ifdebug(2){
573  pips_debug(2, "R/W effects: \n");
574  (*effects_prettyprint_func)(l_loop);
575  }
576  store_rw_effects_list(current_stat, l_loop);
577  pips_debug(2, "end\n");
578 }
579 
580 static void rw_effects_of_call(call c)
581 {
583  transformer context = (*load_context_func)(current_stat);
584  list le = NIL;
585 
586  pips_debug(2, "begin call to %s\n", entity_name(call_function(c)));
587 
588  if (!(*empty_context_test)(context))
589  {
590  list sel = load_proper_rw_effects_list(current_stat);
591  le = effects_dup(sel);
592  ifdebug(2){
593  pips_debug(2, "proper effects before summarization: \n");
594  (*effects_prettyprint_func)(le);
595  }
596  if (contract_p)
597  le = proper_to_summary_effects(le);
598  }
599  else
600  pips_debug(2, "empty context\n");
601 
602  // functions that can be pointed by effects_descriptor_normalize_func:
603  // simple_effects_descriptor_normalize
604  // convex_effects_descriptor_normalize
605  (*effects_descriptor_normalize_func)(le);
606 
607  ifdebug(2){
608  pips_debug(2, "R/W effects: \n");
609  (*effects_prettyprint_func)(le);
610  }
611  store_rw_effects_list(current_stat, le);
612 
613  pips_debug(2, "end\n");
614 }
615 
616 /* For the time being, just a duplicate of rw_effects_of_call() */
617 static void rw_effects_of_application(application a __attribute__ ((__unused__)))
618 {
620  transformer context = (*load_context_func)(current_stat);
621  list le = NIL;
622 
623  pips_debug(2, "begin application\n");
624 
625  if (!(*empty_context_test)(context))
626  {
627  list sel = load_proper_rw_effects_list(current_stat);
628  le = effects_dup(sel);
629  ifdebug(2){
630  pips_debug(2, "proper effects before summarization: \n");
631  (*effects_prettyprint_func)(le);
632  }
633  if (contract_p)
634  le = proper_to_summary_effects(le);
635  }
636  else
637  pips_debug(2, "empty context\n");
638 
639  // functions that can be pointed by effects_descriptor_normalize_func:
640  // simple_effects_descriptor_normalize
641  // convex_effects_descriptor_normalize
642  (*effects_descriptor_normalize_func)(le);
643 
644  ifdebug(2){
645  pips_debug(2, "R/W effects: \n");
646  (*effects_prettyprint_func)(le);
647  }
648  store_rw_effects_list(current_stat, le);
649 
650  pips_debug(2, "end\n");
651 }
652 
653 /* Just to handle one kind of instruction, expressions which are not
654  calls. As we do not distinguish between Fortran and C, this
655  function is called for Fortran module although it does not have any
656  effect.
657  */
658 static void rw_effects_of_expression_instruction(instruction i)
659 {
660  //list l_proper = NIL;
662  //instruction inst = statement_instruction(current_stat);
663 
664  /* Is the call an instruction, or a sub-expression? */
665  if (instruction_expression_p(i)) {
667  syntax is = expression_syntax(ie);
668  call c = call_undefined;
669 
670  if(syntax_cast_p(is)) {
672  syntax sc = expression_syntax(ce);
673 
674  if(syntax_call_p(sc)) {
675  c = syntax_call(sc);
676  rw_effects_of_call(c);
677  }
678  else if(syntax_reference_p(sc)) {
679  /* FI: I guess you do not end up here if the cast appears in
680  the lhs, assuming this is till compatible with the
681  standard. */
682  /* reference r = syntax_reference(sc); */
683  // FI: Copied from below
684  store_rw_effects_list(current_stat, NIL);
685  }
686  else {
687  pips_internal_error("Cast case not implemented");
688  }
689  }
690  else if(syntax_call_p(is)) {
691  /* This may happen when a loop is desugared into an unstructured. */
692  c = syntax_call(is);
693  rw_effects_of_call(c);
694  }
695  else if(syntax_application_p(is)) {
697  //expression fe = application_function(a);
698 
699  pips_user_warning("Cumulated effects of call site using function "
700  "pointers in data structures are ignored for the time being\n");
701  rw_effects_of_application(a);
702  }
703  else if (syntax_reference_p(is)) {
704  // someone typed "i;" in the code... it is allowed.
705  // let us ignore this dead code for today
706  // shoud generate a read effect on the reference?
707  // can it be safely ignored?
708  store_rw_effects_list(current_stat, NIL);
709  }
710  else {
711  pips_internal_error("Instruction expression case not implemented");
712  }
713 
714  pips_debug(2, "Effects for expression instruction in statement%03zd\n",
715  statement_ordering(current_stat));
716 
717  }
718 }
719 
720 static void rw_effects_of_test(test t)
721 {
723  list le, lt, lf, lc, lr;
724  statement true_s = test_true(t);
725  statement false_s = test_false(t);
726 
727  pips_debug(2, "begin\n");
728 
729  /* FI: when regions are computed the test condition should be
730  * evaluated wrt the current precondition to see if it evaluates
731  * to true or false. This would preserve must effects.
732  *
733  * dead_test_filter() could be used, but it returns an enum
734  * defined in transformations-local.h
735  */
736 
738  !(*stmt_strongly_feasible_p_func)(true_s)) {
739  /* the true branch is dead */
740  le = effects_dup(load_rw_effects_list(false_s));
741  }
743  !(*stmt_strongly_feasible_p_func)(false_s)) {
744  /* the false branch is dead */
745  le = effects_dup(load_rw_effects_list(true_s));
746  }
747  else {
748  /* effects of the true branch */
750  /* effects of the false branch */
752  /* effects of the combination of both
753  *
754  * The region intersection in the corresponding equation, at the
755  * bottom of page 297 in Beatrice Creusillet's PhD, is not used to
756  * compute MUST regions.
757  *
758  * Also, the impact of the test condition is assumed taken into
759  * account at a lower level, via the preconditions.
760  */
761  // functions that can be pointed by effects_test_union_op:
762  // EffectsMayUnion
763  // RegionsMayUnion
764  // ReferenceTestUnion
765  le = (*effects_test_union_op)(lt, lf, effects_same_action_p);
766  }
767 
768  /* proper_effects of the condition */
769  lc = effects_dup(load_proper_rw_effects_list(current_stat));
770  if (contract_p)
771  lc = proper_to_summary_effects(lc);
772  /* effect of the test */
773  // functions that can be pointed by effects_union_op:
774  // ProperEffectsMustUnion
775  // RegionsMustUnion
776  // ReferenceUnion
777  // EffectsMustUnion
778  lr = (*effects_union_op)(le, lc, effects_same_action_p);
779 
780  // functions that can be pointed by effects_descriptor_normalize_func:
781  // simple_effects_descriptor_normalize
782  // convex_effects_descriptor_normalize
783  (*effects_descriptor_normalize_func)(lr);
784 
785  ifdebug(2){
786  pips_debug(2, "R/W effects: \n");
787  (*effects_prettyprint_func)(lr);
788  }
789 
790  store_rw_effects_list(current_stat, lr);
791  pips_debug(2, "end\n");
792 }
793 
794 static void save_useful_variables_effects(entity ent, list l_eff) {
795  list l_save = NIL;
797 
798  FOREACH(EFFECT, ef, l_eff) {
800  // copy_effect is need because of the save and free by pipsdbm
801  l_save = CONS(EFFECT, copy_effect(ef), l_save);
802  }
803  }
804  ifdebug(2) {
805  pips_debug(2, "add useful_variables_effects/regions for entity %s :\n", entity_name(ent));
806  (*effects_prettyprint_func)(l_save);
807  }
808  eff = make_effects(l_save);
809 
811 }
812 
813 
814 /**
815  computes the cumulated effects of the declaration from the list of
816  effects that occur after the declaration
817 
818  @param[out] lrw_before_decl is the list of effects in the store before the declaration;
819  it is a modified version of lrw_after_first_decl.
820  @param[inout] lrw_after_first_decl is the list of effects in the store after the declaration;
821  lrw_after_first_decl can be freed after this function.
822  @param[in] decl is the declared variable
823 
824  possible usage: l = rw_effects_of_declaration(l, decl)
825 
826  This is used at least in rw_effects_of_sequence to compute the
827  cumulated effect of a sequence. The statements are walked backward
828  from the last one to the first one. Each time a declaration is hit,
829  the declared variables are also analyzed backwards to project past
830  effects that cannot be moved up because the variables is no longer
831  in the environment.
832 
833  For reasons I (FI) still do not understand, the effect of
834  initialization expressions are (re(re?)?) computed here. At least
835  when this code is used for the computation of the cumulated
836  effects, I'd rather use the statement effects, whether they are
837  declarations or not and only filter them, igonring initialization
838  expressions if any.
839 
840  This function has been outlined from
841  rw_effects_of_declaration(). The names of the local variables
842  should probably be updated according to its signature and
843  semantics.
844  */
845 static list rw_effects_of_declaration(list lrw_after_first_decl, entity decl)
846 {
847  list lrw_before_decls = NIL; /* the returned list */
848  storage decl_s = entity_storage(decl);
849 
850  ifdebug(8) {
851  type ct = entity_basic_concrete_type(decl);
852  pips_debug(8, "dealing with entity : %s with type %s\n",
853  entity_local_name(decl), string_of_type(ct));
854  }
855 
856  if (storage_ram_p(decl_s)
857  /* static variable declaration has no effect, even in case of initialization. */
859  && type_variable_p(entity_type(decl)))
860  {
861  value v_init = entity_initial(decl);
862  expression exp_init = expression_undefined;
863  if(value_expression_p(v_init))
864  exp_init = value_expression(v_init);
865 
866  // add the effects due to the initialization part
867  if(/*false &&*/ !expression_undefined_p(exp_init))
868  {
869  pips_debug(8, "initial value: %s\n", expression_to_string(exp_init));
870  list l_exp_init = generic_proper_effects_of_expression(exp_init);
871  if (contract_p)
872  l_exp_init = proper_to_summary_effects(l_exp_init);
873  // functions that can be pointed by effects_union_op:
874  // ProperEffectsMustUnion
875  // RegionsMustUnion
876  // ReferenceUnion
877  // EffectsMustUnion
878  lrw_after_first_decl = (*effects_union_op)(l_exp_init,
879  lrw_after_first_decl, effects_same_action_p);
880  }
881 
882  save_useful_variables_effects(decl, lrw_after_first_decl);
883 
884  // filter l_rw_after_decls with the declaration
885  lrw_before_decls = filter_effects_with_declaration(lrw_after_first_decl, decl);
886 
887  } /* if (storage_ram(decl_s) && !static_area_p(ram_section(storage_ram(decl_s)))) */
888  else
889  {
890  lrw_before_decls = lrw_after_first_decl;
891  }
892  return lrw_before_decls;
893 }
894 
895 /**
896  computes the cumulated effects of the declarations from the list of
897  effects after the declaration and make sure that all effects are
898  constant (FI: with respect to dereferencements I guess) to be sure
899  that can be unioned properly.
900 
901  @param[out] lrw_after_decls is the list of effects in the store after the declarations;
902  it is modified.
903  @param[in] l_decl is the ordered list of declarations.
904 
905  usage: l = rw_effects_of_declarations(l, l_decl)
906  */
907 static list rw_effects_of_declarations(list lrw_after_decls, list l_decl)
908 {
909  list lrw_before_decls = NIL; /* the returned list */
910  list lrw_after_first_decl = NIL; /* effects after first declaration */
911 
912  if (!ENDP(l_decl))
913  {
914  // treat last declarations first: n recursive calls instead of a
915  // gen_reverse()...
916  if (!ENDP(CDR(l_decl)))
917  lrw_after_first_decl = rw_effects_of_declarations(lrw_after_decls, CDR(l_decl));
918  else
919  lrw_after_first_decl = lrw_after_decls;
920  // then handle top declaration
921  entity decl = ENTITY(CAR(l_decl));
922  lrw_before_decls = rw_effects_of_declaration(lrw_after_first_decl, decl);
923 
924  } /* if (!ENDP(CDR(l_decl))) */
925  else
926  lrw_before_decls = lrw_after_decls;
927  // we should also do some kind of unioning...
928 
929  if (get_constant_paths_p()) {
930  list l_tmp = lrw_before_decls;
931  lrw_before_decls = pointer_effects_to_constant_path_effects(lrw_before_decls);
932  effects_free(l_tmp);
933  }
934 
935  return lrw_before_decls;
936 }
937 
938 /* Compute backwards the cumulated effects of the non-empty statement
939  * list "sl" as it is necessary to translate convex effects into
940  * the initial state.
941  *
942  * To do so, call recursively r_rw_effects_of_sequence() on the CDR of
943  * "sl" and translate them in the current state thanks to "t1", the
944  * transformer of the first statement, "s1", add the effects of the
945  * first statement "s1" which are already available in that same
946  * state, and remove effects related to variables declared in the
947  * first statement, "s1".
948  *
949  * rw_effects(sl) = projection(rw_effects(CDR(sl)) o transformer(s1)
950  * U effects(s1),
951  * declarations(s1))
952  *
953  * The implementation is slightly different from the equations above
954  * if the first statement is a C declaration statement. The effect of
955  * the first statement are neglected at first and the effects of the
956  * initialization expressions are added later:
957  *
958  * rw_effects(sl) = if(declaration_p(s1)) then
959  * projection(rw_effects(CDR(sl)) o transformer(s1),
960  * declarations(s1))
961  * U effects(initializations(s1))
962  * else
963  * rw_effects(CDR(l_inst)) o transformer(s1)
964  * U effects(s1)
965  *
966  * In both cases, a special process is used when "sl" is a singleton list:
967  *
968  * rw_effects(sl) = if(constant_p) then
969  * constant_effects(projection(effects(s1), declaration(s1)))
970  * else
971  * projection(effects(s1), declaration(s1))
972  *
973  * This equation is altered with the implemented scheme because
974  * "effects(s1)" is not used when "s1" is a declaration.
975  *
976  * The precondition of "s1", called "context" is also used and should
977  * appear in the equations above.
978  *
979  * Note that the recursion performed here is independent of the global
980  * gen_multi_recurse(). The contexts have to be maintained explicitely.
981  */
982 static list r_rw_effects_of_sequence(list sl)
983 {
984  statement s1 = STATEMENT(CAR(sl));
985  list remaining_block = CDR(sl);
986 
987  list s1_lrw; /* rw effects of first statement */
988  list rb_lrw; /* rw effects of remaining block */
989  list l_rw = NIL; /* resulting rw effects */
990  list l_decl = NIL; /* declarations if first_statement is a declaration statement */
991 
992  /* Precondition of s1. Could be called p1... */
993  // for effects, context=transformer_undefined
994  transformer context = (*load_context_func)(s1);
996  /* This is used to retrieve the points-to information */
998  /* To obtain precise warning and error messages */
1000 
1003  // if it's a declaration statement, effects will be added on the fly
1004  // as declarations are handled.
1005  pips_debug(5, "first statement is a declaration statement\n");
1006  l_decl = statement_declarations(s1);
1007  s1_lrw = NIL;
1008  //s1_lrw = load_rw_effects_list(s1);
1009  }
1010  else
1011  s1_lrw = load_rw_effects_list(s1);
1012 
1013  /* Is it the last instruction of the block? */
1014  if (!ENDP(remaining_block)) {
1015  rb_lrw = r_rw_effects_of_sequence(remaining_block);
1016 
1017  ifdebug(3) {
1018  pips_debug(3, "R/W effects of first statement: \n");
1019  (*effects_prettyprint_func)(s1_lrw);
1020  pips_debug(3, "R/W effects of remaining sequence: \n");
1021  (*effects_prettyprint_func)(rb_lrw);
1022  /*
1023  transformer t1 = (*load_transformer_func)(s1);
1024  if (!transformer_undefined_p(t1)) {
1025  pips_debug(3, "transformer of first statement:\n");
1026  fprint_transformer(stderr, t1, (get_variable_name_t) entity_local_name);
1027  //print_transformer(t1);
1028  }
1029  if (!transformer_undefined_p(context)) {
1030  pips_debug(3, "Precondition of first statement:\n");
1031  fprint_transformer(stderr, context, (get_variable_name_t) entity_local_name);
1032  //print_transformer(t1);
1033  }
1034  */
1035  }
1036  if (rb_lrw !=NIL) {
1037  /* FI: I do not understand this update; do we store each
1038  * partial accumulation of effects at each statement? */
1039  /* NL: It's not an update of the resource but of the store effects */
1040  rb_lrw = generic_effects_store_update(rb_lrw, s1, true);
1041  }
1042  else {
1043  ifdebug(3){
1044  pips_debug(3, "Warning - no effect on remaining block\n");
1045  }
1046  }
1047  ifdebug(5){
1048  pips_debug(5, "R/W effects of remaining sequence "
1049  "after store update: \n");
1050  (*effects_prettyprint_func)(rb_lrw);
1051  }
1052 
1053  /* then take care of declarations if any: project effects
1054  * based on declared variables and add effects of
1055  * initialization expressions and translate non constant
1056  * effects into constant effects if necessary. */
1058  rb_lrw = rw_effects_of_declarations(rb_lrw, l_decl);
1060 
1061  ifdebug(5){
1062  pips_debug(5, "R/W effects of remaining sequence "
1063  "after taking declarations into account: \n");
1064  (*effects_prettyprint_func)(rb_lrw);
1065  }
1066 
1067  /* RW(block) = RW(rest_of_block) U RW(s1) */
1068  // functions that can be pointed by effects_union_op:
1069  // ProperEffectsMustUnion
1070  // RegionsMustUnion
1071  // ReferenceUnion
1072  // EffectsMustUnion
1073  l_rw = (*effects_union_op)(rb_lrw, effects_dup(s1_lrw), effects_same_action_p);
1074 
1075  ifdebug(5){
1076  pips_debug(5, "R/W effects of remaining sequence "
1077  "after union: \n");
1078  (*effects_prettyprint_func)(l_rw);
1079  }
1080  }
1081  else {
1082  /* We are on the last statement of the block and end the recursion */
1083  /* If l_decl is not empty, then s1_lrw is empty, and
1084  * vice-versa. See prologue. */
1085  l_rw = rw_effects_of_declarations(effects_dup(s1_lrw), l_decl);
1086  /* This should be useless because cumulated effects are applied
1087  * to constant proper effects most of the time... Maybe it is
1088  * useful for cumulated pointer effects? */
1089  if (get_constant_paths_p()) {
1090  list l_tmp = l_rw;
1092  effects_free(l_tmp);
1093  }
1094  }
1095 
1099 
1100  return(l_rw);
1101 }
1102 
1103 /* The real work is performed by r_rw_effects_of_sequence(), the
1104  * recursive backward walk of the sequence.
1105  *
1106  * Here, anywhere effects are dealt with, the effects are normalized
1107  * and store in the cumulate effects mapping.
1108  *
1109  * Empty sequences are also dealt with directly here.
1110  */
1111 static void rw_effects_of_sequence(sequence seq)
1112 {
1114  list le = NIL;
1116 
1117  pips_debug(2, "begin\n");
1118 
1119  if (ENDP(l_inst))
1120  {
1121  if (get_bool_property("WARN_ABOUT_EMPTY_SEQUENCES"))
1122  pips_user_warning("empty sequence\n");
1123  }
1124  else
1125  {
1126  list l_tmp = r_rw_effects_of_sequence(l_inst);
1127  le = clean_anywhere_effects(l_tmp);
1128  gen_full_free_list(l_tmp);
1129  }
1130 
1131  ifdebug(2){
1132  pips_debug(2, "R/W effects: \n");
1133  (*effects_prettyprint_func)(le);
1134  }
1135 
1136  // functions that can be pointed by effects_descriptor_normalize_func:
1137  // simple_effects_descriptor_normalize
1138  // convex_effects_descriptor_normalize
1139  (*effects_descriptor_normalize_func)(le);
1140 
1141  ifdebug(2){
1142  pips_debug(2, "R/W effects after normalization: \n");
1143  (*effects_prettyprint_func)(le);
1144  }
1145 
1146  store_rw_effects_list(current_stat, le);
1147  pips_debug(2, "end\n");
1148 }
1149 
1150 static bool rw_effects_stmt_filter(statement s)
1151 {
1152  pips_debug(1, "Entering statement with ordering: %03zd and number: %03zd\n", statement_ordering(s), statement_number(s));
1153  ifdebug(4) {
1154  print_statement(s);
1155  }
1158  return(true);
1159 }
1160 
1161 static void rw_effects_of_statement(statement s)
1162 {
1166  pips_debug(1, "End statement %03zd :\n", statement_ordering(s));
1167 }
1168 
1169 static bool r_effects_of_return_exit_abort_statment(statement s, list lem) {
1170  if (statement_call_p(s)) {
1171  if (return_statement_p(s)
1172  || exit_statement_p(s)
1173  || abort_statement_p(s)) {
1174  list le = load_rw_effects_list(s);
1175  FOREACH(EFFECT, e, lem) {
1176  if (io_effect_p(e)) {
1177  if (effect_read_p(e)) {
1178  le = gen_nconc(le, CONS(EFFECT, e, NIL));
1179  }
1180  }
1181  }
1182  update_rw_effects_list(s, le);
1183  }
1184  return false;
1185  }
1186  return true;
1187 }
1188 
1189 
1190 void rw_effects_of_module_statement(statement module_stat)
1191 {
1194  make_statement_global_stack(); // for calls to semantics libray
1195  pips_debug(1,"begin\n");
1196 
1197  gen_multi_recurse(module_stat,
1198  statement_domain, rw_effects_stmt_filter, rw_effects_of_statement,
1199  sequence_domain, gen_true, rw_effects_of_sequence,
1200  test_domain, gen_true, rw_effects_of_test,
1201  call_domain, gen_true, rw_effects_of_call,
1202  loop_domain, gen_true, rw_effects_of_loop,
1203  whileloop_domain, gen_true, rw_effects_of_while,
1204  forloop_domain, gen_true, rw_effects_of_forloop,
1205  unstructured_domain, gen_true, rw_effects_of_unstructured,
1206  instruction_domain, gen_true, rw_effects_of_expression_instruction,
1207  expression_domain, gen_false, gen_null, /* NOT THESE CALLS */
1208  NULL);
1209 
1211  list le = load_rw_effects_list(module_stat);
1212 
1213  gen_context_recurse(module_stat, le,
1214  statement_domain, r_effects_of_return_exit_abort_statment, gen_null2);
1215  }
1216 
1217  pips_debug(1,"end\n");
1220  free_statement_global_stack(); // for calls to semantics library
1221 }
1222 
1223 bool rw_effects_engine(const char * module_name)
1224 {
1225  /* Get the code of the module. */
1227  db_get_memory_resource(DBR_CODE, module_name, true));
1229 
1231 
1232  // functions that can be pointed by effects_computation_init_func:
1233  // effects_computation_no_init
1234  // init_convex_in_out_regions
1235  // init_convex_rw_regions
1236  (*effects_computation_init_func)(module_name);
1237 
1238  /* We also need the proper effects of the module */
1240 
1241  /* Compute the rw effects or references of the module. */
1242  init_rw_effects();
1245 
1248  db_get_memory_resource(DBR_POINTS_TO, module_name, true) );
1251 
1252 
1253  debug_on("EFFECTS_DEBUG_LEVEL");
1254  pips_debug(1, "begin\n");
1255 
1257 
1258  pips_debug(1, "end\n");
1259  debug_off();
1260 
1262  reset_pt_to_list();
1264  reset_pv();
1265 
1266  (*db_put_rw_effects_func)
1268  (*db_put_invariant_rw_effects_func)
1270  (*db_put_useful_variables_effects_func)
1272 
1276  reset_rw_effects();
1279 
1280  // functions that can be pointed by effects_computation_reset_func:
1281  // effects_computation_no_reset
1282  // reset_convex_in_out_regions
1283  // reset_convex_rw_regions
1284  (*effects_computation_reset_func)(module_name);
1285  return(true);
1286 }
1287 
1288 
float a2sf[2] __attribute__((aligned(16)))
USER generates a user error (i.e., non fatal) by printing the given MSG according to the FMT.
Definition: 3dnow.h:3
effects make_effects(list a)
Definition: effects.c:568
effect copy_effect(effect p)
EFFECT.
Definition: effects.c:448
reference make_reference(entity a1, list a2)
Definition: ri.c:2083
list l_inst
The list "first" is a truncated list from the first to the current statement (not included).
Definition: atomizer.h:87
@ with_points_to
@ with_pointer_values
void free_effects_private_current_context_stack(void)
list make_anywhere_read_write_memory_effects(void)
void reset_useful_variables_effects(void)
void set_rw_effects(statement_effects)
void effects_to_may_effects(list)
bool(* empty_context_test)(transformer)
void make_effects_private_current_context_stack(void)
void set_contracted_rw_effects(bool)
rw_effects_engine.c
transformer(* load_context_func)(statement)
void make_effects_private_current_stmt_stack(void)
utils.c
list proper_to_summary_effects(list)
pointer_info_val get_pointer_info_kind(void)
void store_rw_effects_list(statement, list)
void init_useful_variables_effects(void)
list load_proper_rw_effects_list(statement)
entity_effects get_useful_variables_effects(void)
transformer transformer_remove_variable_and_dup(transformer, entity)
void init_rw_effects(void)
statement effects_private_current_stmt_pop(void)
void store_useful_variables_effects(entity, effects)
list proper_effects_combine(list, bool)
void reset_proper_rw_effects(void)
void free_effects_private_current_stmt_stack(void)
list clean_anywhere_effects(list)
list generic_effects_store_update(list, statement, bool)
void rw_effects_of_module_statement(statement)
void set_proper_rw_effects(statement_effects)
void effects_free(list)
bool check_sdfi_effects_p(entity, list)
statement effects_private_current_stmt_head(void)
void update_rw_effects_list(statement, list)
void effects_private_current_stmt_push(statement)
bool summary_rw_effects_engine(const char *)
list effects_dup(list)
void update_invariant_rw_effects_list(statement, list)
bool rw_effects_engine(const char *)
list filter_effects_with_declaration(list, entity)
list load_rw_effects_list(statement)
bool get_constant_paths_p(void)
statement_effects get_rw_effects(void)
list generic_proper_effects_of_expression(expression)
void init_invariant_rw_effects(void)
void reset_invariant_rw_effects(void)
void store_invariant_rw_effects_list(statement, list)
transformer effects_private_current_context_pop(void)
void effects_private_current_context_push(transformer)
list effects_dup_without_variables(list, list)
list pointer_effects_to_constant_path_effects(list)
statement_effects(* db_get_proper_rw_effects_func)(const char *)
list generic_effect_generate_all_accessible_paths_effects(effect, type, tag)
void reset_rw_effects(void)
bool effects_same_action_p(effect, effect)
list summary_effects_from_declaration(const char *)
bool(* stmt_strongly_feasible_p_func)(statement)
statement_effects get_invariant_rw_effects(void)
statement_effects(* db_get_rw_effects_func)(const char *)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define effect_read_p(eff)
#define effect_scalar_p(eff) entity_scalar_p(effect_entity(eff))
entity effect_entity(effect)
cproto-generated files
Definition: effects.c:52
action make_action_write_memory(void)
To ease the extension of action with action_kind.
Definition: effects.c:1011
void set_pt_to_list(statement_points_to)
void reset_pt_to_list(void)
bool io_effect_p(effect)
Definition: effects.c:501
#define effects_undefined
Definition: effects.h:688
#define effect_action(x)
Definition: effects.h:642
#define action_write_p(x)
Definition: effects.h:314
#define descriptor_undefined
Definition: effects.h:559
#define EFFECT(x)
EFFECT.
Definition: effects.h:608
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
Definition: genC.h:285
void gen_full_free_list(list l)
Definition: genClib.c:1023
#define CONTROL_MAP(ctl, code, c, list)
Macro to walk through all the controls reachable from a given control node of an unstructured.
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_null2(__attribute__((unused)) void *u1, __attribute__((unused)) void *u2)
idem with 2 args, to please overpeaky compiler checks
Definition: genClib.c:2758
bool gen_false(__attribute__((unused)) gen_chunk *unused)
Return false and ignore the argument.
Definition: genClib.c:2796
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
bool loop_parallel_p(loop l)
Test if a loop is parallel.
Definition: loop.c:393
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
size_t gen_length(const list l)
Definition: list.c:150
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
list gen_append(list l1, const list l2)
Definition: list.c:471
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
bool statement_call_p(statement)
Definition: statement.c:364
bool empty_statement_p(statement)
Test if a statement is empty.
Definition: statement.c:391
bool return_statement_p(statement)
Test if a statement is a C or Fortran "return".
Definition: statement.c:172
bool exit_statement_p(statement)
Definition: statement.c:177
bool abort_statement_p(statement)
Definition: statement.c:182
bool declaration_statement_p(statement)
Had to be optimized according to Beatrice Creusillet.
Definition: statement.c:224
#define debug_on(env)
Definition: misc-local.h:157
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_user_warning
Definition: misc-local.h:146
#define pips_internal_error
Definition: misc-local.h:149
#define debug_off()
Definition: misc-local.h:160
#define pips_user_error
Definition: misc-local.h:147
void set_pv(statement_cell_relations)
statement_cell_relations db_get_simple_pv(const char *)
I don't know how to deal with these mappings if we have to analyse several modules at the same time w...
void reset_pv(void)
string expression_to_string(expression e)
Definition: expression.c:77
string string_of_type(const type)
Definition: type.c:56
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
#define unstructured_control
After the modification in Newgen: unstructured = entry:control x exit:control we have create a macro ...
bool static_area_p(entity aire)
Definition: area.c:77
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 same_entity_p(entity e1, entity e2)
predicates on entities
Definition: entity.c:1321
bool c_module_p(entity m)
Test if a module "m" is written in C.
Definition: entity.c:2777
entity module_name_to_entity(const char *mn)
This is an alias for local_name_to_top_level_entity.
Definition: entity.c:1479
bool entity_main_module_p(entity e)
Definition: entity.c:700
const char * label_local_name(entity e)
END_EOLE.
Definition: entity.c:604
list module_formal_parameters(entity func)
list module_formal_parameters(entity func) input : an entity representing a function.
Definition: module.c:327
type ultimate_type(type)
Definition: type.c:3466
statement pop_statement_global_stack(void)
Definition: static.c:352
type entity_basic_concrete_type(entity)
retrieves or computes and then returns the basic concrete type of an entity
Definition: type.c:3677
void push_statement_on_statement_global_stack(statement)
Definition: static.c:333
void free_statement_global_stack(void)
Definition: static.c:358
void make_statement_global_stack(void)
Definition: static.c:318
#define forloop_domain
newgen_extensions_domain_defined
Definition: ri.h:178
#define loop_body(x)
Definition: ri.h:1644
#define test_domain
newgen_entity_domain_defined
Definition: ri.h:418
#define syntax_reference_p(x)
Definition: ri.h:2728
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154
#define unstructured_domain
newgen_type_domain_defined
Definition: ri.h:442
#define forloop_initialization(x)
Definition: ri.h:1366
#define call_function(x)
Definition: ri.h:709
#define reference_variable(x)
Definition: ri.h:2326
#define loop_domain
newgen_language_domain_defined
Definition: ri.h:218
#define control_predecessors(x)
Definition: ri.h:943
#define forloop_increment(x)
Definition: ri.h:1370
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define syntax_call_p(x)
Definition: ri.h:2734
#define statement_ordering(x)
Definition: ri.h:2454
#define syntax_cast(x)
Definition: ri.h:2739
#define type_functional(x)
Definition: ri.h:2952
#define syntax_application(x)
Definition: ri.h:2748
#define test_false(x)
Definition: ri.h:2837
#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
#define storage_ram_p(x)
Definition: ri.h:2519
#define instruction_domain
newgen_functional_domain_defined
Definition: ri.h:202
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
#define ram_section(x)
Definition: ri.h:2249
#define cast_expression(x)
Definition: ri.h:747
#define expression_undefined
Definition: ri.h:1223
#define entity_name(x)
Definition: ri.h:2790
#define functional_parameters(x)
Definition: ri.h:1442
#define test_true(x)
Definition: ri.h:2835
#define sequence_statements(x)
Definition: ri.h:2360
#define syntax_call(x)
Definition: ri.h:2736
#define control_successors(x)
Definition: ri.h:945
#define loop_label(x)
Definition: ri.h:1646
#define loop_locals(x)
Definition: ri.h:1650
#define instruction_expression(x)
Definition: ri.h:1541
#define syntax_application_p(x)
Definition: ri.h:2746
#define expression_undefined_p(x)
Definition: ri.h:1224
#define variable_dimensions(x)
Definition: ri.h:3122
#define whileloop_body(x)
Definition: ri.h:3162
#define whileloop_domain
newgen_variable_domain_defined
Definition: ri.h:466
#define statement_declarations(x)
Definition: ri.h:2460
#define storage_ram(x)
Definition: ri.h:2521
#define loop_range(x)
Definition: ri.h:1642
#define forloop_condition(x)
Definition: ri.h:1368
#define syntax_cast_p(x)
Definition: ri.h:2737
#define control_statement(x)
Definition: ri.h:941
#define entity_type(x)
Definition: ri.h:2792
#define call_undefined
Definition: ri.h:685
#define statement_number(x)
Definition: ri.h:2452
#define value_expression_p(x)
Definition: ri.h:3080
#define expression_syntax(x)
Definition: ri.h:1247
#define sequence_domain
newgen_reference_domain_defined
Definition: ri.h:346
#define type_variable_p(x)
Definition: ri.h:2947
#define forloop_body(x)
Definition: ri.h:1372
#define value_expression(x)
Definition: ri.h:3082
#define loop_index(x)
Definition: ri.h:1640
#define instruction_expression_p(x)
Definition: ri.h:1539
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
#define entity_initial(x)
Definition: ri.h:2796
s1
Definition: set.c:247
#define ifdebug(n)
Definition: sg.c:47
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
Definition: delay.c:253