PIPS
interface.c
Go to the documentation of this file.
1 /*
2 
3  $Id: interface.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 simple effects : Be'atrice Creusillet 5/97
28  *
29  * File: interface.c
30  * ~~~~~~~~~~~~~~~~~
31  *
32  * This File contains.
33  *
34  */
35 
36 #include <stdio.h>
37 #include <string.h>
38 
39 #include "genC.h"
40 #include "linear.h"
41 #include "ri.h"
42 #include "effects.h"
43 
44 #include "misc.h"
45 #include "ri-util.h"
46 #include "prettyprint.h" // for debugging
47 #include "effects-util.h"
48 #include "properties.h"
49 #include "database.h"
50 #include "resources.h"
51 #include "effects-generic.h"
52 #include "effects-simple.h"
53 
54 /****************************************************** PIPSMAKE INTERFACES */
55 
56 /* SPECIFIC INTERFACES */
57 
58 bool cumulated_references(const string module_name)
59 {
60  bool ok;
61  set_constant_paths_p(false);
66  return ok;
67 }
68 
69 bool proper_references(const string module_name)
70 {
71  bool ok;
72  set_constant_paths_p(false);
77  return ok;
78 }
79 
80 
81 bool proper_pointer_effects(const string module_name)
82 {
83  bool ok;
84  set_constant_paths_p(false);
89  return ok;
90 }
91 
92 bool summary_pointer_effects(const string module_name)
93 {
94  bool ok;
95  set_constant_paths_p(false);
100  return ok;
101 }
102 
103 bool cumulated_pointer_effects(const string module_name)
104 {
105  bool ok;
106  set_constant_paths_p(false);
111  return ok;
112 }
113 
115 {
116  bool ok;
117  set_constant_paths_p(false);
122  return ok;
123 }
124 
126 {
127  bool ok;
128  set_constant_paths_p(false);
133  return ok;
134 }
135 
136 bool proper_effects(const string module_name)
137 {
138  bool ok;
139  if (! c_module_p(module_name_to_entity(module_name)) || !get_bool_property("CONSTANT_PATH_EFFECTS"))
140  set_constant_paths_p(false);
141  else
142  set_constant_paths_p(true);
147  return ok;
148 }
149 
151 {
152  bool ok;
153  set_constant_paths_p(true);
158  return ok;
159 }
160 
162 {
163  bool ok;
164  set_constant_paths_p(true);
169  return ok;
170 }
171 
172 bool summary_effects(const string module_name)
173 {
174  bool ok;
175  if (! c_module_p(module_name_to_entity(module_name)) || !get_bool_property("CONSTANT_PATH_EFFECTS"))
176  set_constant_paths_p(false);
177  else
178  set_constant_paths_p(true);
181  // This is dealt with by set_current_phase_context()
182  //entity_basic_concrete_types_init();
185  //entity_basic_concrete_types_reset();
186  return ok;
187 }
188 
189 bool cumulated_effects(const string module_name)
190 {
191  bool ok;
192  if (! c_module_p(module_name_to_entity(module_name)) || !get_bool_property("CONSTANT_PATH_EFFECTS"))
193  set_constant_paths_p(false);
194  else
195  set_constant_paths_p(true);
200  return ok;
201 }
202 
204 {
205  bool ok;
206  set_constant_paths_p(true);
211  return ok;
212 }
213 
215 {
216  bool ok;
217  set_constant_paths_p(true);
222  return ok;
223 }
224 
225 bool in_summary_effects(const string module_name)
226 {
227  bool ok;
228  if (! c_module_p(module_name_to_entity(module_name)) || !get_bool_property("CONSTANT_PATH_EFFECTS"))
229  set_constant_paths_p(false);
230  else
231  set_constant_paths_p(true);
236  return ok;
237 }
238 
239 bool out_summary_effects(const string module_name)
240 {
241  bool ok;
242  if (! c_module_p(module_name_to_entity(module_name)) || !get_bool_property("CONSTANT_PATH_EFFECTS"))
243  set_constant_paths_p(false);
244  else
245  set_constant_paths_p(true);
251  return ok;
252 }
253 
254 bool in_effects(const string module_name)
255 {
256  bool ok;
257  if (! c_module_p(module_name_to_entity(module_name)) || !get_bool_property("CONSTANT_PATH_EFFECTS"))
258  set_constant_paths_p(false);
259  else
260  set_constant_paths_p(true);
266  return ok;
267 }
268 
269 bool out_effects(const string module_name)
270 {
271  bool ok;
272  if (! c_module_p(module_name_to_entity(module_name)) || !get_bool_property("CONSTANT_PATH_EFFECTS"))
273  set_constant_paths_p(false);
274  else
275  set_constant_paths_p(true);
280  return ok;
281 }
282 
283 /************************************************************* PRETTYPRINTS */
284 
285 static bool
286 print_code_effects(
287  const char* module_name,
289  bool is_user_view,
290  bool is_attached,
291  string resource_name,
292  string summary_resource_name,
293  string suffix)
294 {
295  bool ok;
296 
297  if (ac_inter == act_rw)
299  else if (ac_inter == act_inout)
301  else if (ac_inter == act_live_in)
303  else if (ac_inter == act_live_out)
305  else
306  pips_internal_error("erroneous actions interpretation\n");
307 
310 
312  (module_name, resource_name, summary_resource_name, suffix, false);
313 
315 
316  /* generic_effects_reset_all_methods(); not useful here */
317  return ok;
318 }
319 
321 {
322  return print_code_effects(module_name, act_rw, false, true,
323  DBR_PROPER_POINTER_EFFECTS, string_undefined, ".prop");
324 }
325 
327 {
328  return print_code_effects(module_name, act_rw, false, true,
329  DBR_CUMULATED_POINTER_EFFECTS, DBR_SUMMARY_POINTER_EFFECTS, ".cumu");
330 }
331 
332 bool print_code_proper_effects(const string module_name)
333 {
334  return print_code_effects(module_name, act_rw, false, true,
335  DBR_PROPER_EFFECTS, string_undefined, ".prop");
336 }
337 
338 bool print_code_cumulated_effects(const string module_name)
339 {
340  return print_code_effects(module_name, act_rw, false, true,
341  DBR_CUMULATED_EFFECTS, DBR_SUMMARY_EFFECTS, ".cumu");
342 }
343 
344 bool print_code_proper_references(const string module_name)
345 {
346  return print_code_effects(module_name, act_rw, false, true,
347  DBR_PROPER_REFERENCES, string_undefined, ".propref");
348 }
349 
351 {
352  return print_code_effects(module_name, act_rw, false, true,
353  DBR_CUMULATED_REFERENCES, string_undefined, ".cumuref");
354 }
355 
356 bool print_code_in_effects(const string module_name)
357 {
358  return print_code_effects(module_name, act_inout, false, false,
359  DBR_IN_EFFECTS, DBR_IN_SUMMARY_EFFECTS, ".ineff");
360 }
361 
362 bool print_code_out_effects(const string module_name)
363 {
364  return print_code_effects(module_name, act_inout, false, false,
365  DBR_OUT_EFFECTS, DBR_OUT_SUMMARY_EFFECTS, ".outeff");
366 }
367 
368 bool print_source_proper_effects(const string module_name)
369 {
370  return print_code_effects(module_name, act_rw, true, true,
371  DBR_PROPER_EFFECTS, string_undefined, ".uprop");
372 }
373 
375 {
376  return print_code_effects(module_name, act_rw, true, true,
377  DBR_CUMULATED_EFFECTS, DBR_SUMMARY_EFFECTS, ".ucumu");
378 }
379 
380 bool print_source_in_effects(const string module_name)
381 {
382  return print_code_effects(module_name, false, true, false,
383  DBR_IN_EFFECTS, DBR_IN_SUMMARY_EFFECTS, ".uineff");
384 }
385 
386 bool print_source_out_effects(const string module_name)
387 {
388  return print_code_effects(module_name, act_inout, true, false,
389  DBR_OUT_EFFECTS, DBR_OUT_SUMMARY_EFFECTS, ".uouteff");
390 }
391 
392 bool print_code_as_a_graph_proper_effects(const string mod_name)
393 {
394  bool success;
395 
396  set_bool_property("PRETTYPRINT_UNSTRUCTURED_AS_A_GRAPH", true);
398  set_bool_property("PRETTYPRINT_UNSTRUCTURED_AS_A_GRAPH", false);
399 
400  return success;
401 }
402 
403 bool print_code_as_a_graph_cumulated_effects(const string mod_name)
404 {
405  bool success;
406 
407  set_bool_property("PRETTYPRINT_UNSTRUCTURED_AS_A_GRAPH", true);
409  set_bool_property("PRETTYPRINT_UNSTRUCTURED_AS_A_GRAPH", false);
410 
411  return success;
412 }
413 
414 /********************************************************** OTHER FUNCTIONS */
415 
416 text
418 {
419  text t;
420 
421  set_is_user_view_p(false);
424  DBR_PROPER_POINTER_EFFECTS,
426  false);
428  return t;
429 }
430 
431 text
433 {
434  text t;
435 
436  set_is_user_view_p(false);
439  DBR_CUMULATED_POINTER_EFFECTS,
440  DBR_SUMMARY_POINTER_EFFECTS,
441  false);
443  return t;
444 }
445 
446 text
448 {
449  text t;
450 
451  set_is_user_view_p(false);
454  DBR_PROPER_EFFECTS,
456  false);
458  return t;
459 }
460 
461 text
463 {
464  text t;
465 
466  set_is_user_view_p(false);
469  DBR_CUMULATED_EFFECTS,
470  DBR_SUMMARY_EFFECTS,
471  false);
473  return t;
474 }
475 
476 
477 /*********** INTERFACES TO COMPUTE SIMPLE PROPER EFFECTS FROM OTHER PHASES */
478 
479 /* list proper_effects_of_expression(expression e)
480  * input : an expression and the current context
481  * output : the corresponding list of effects.
482  * modifies : nothing.
483  * comment :
484  */
485 list
487 {
488  list le;
489  bool context_stack_defined_p =
491 
492  if (!context_stack_defined_p)
493  {
496  debug_on("PROPER_EFFECTS_DEBUG_LEVEL");
497  }
498 
502  if (!context_stack_defined_p)
503  {
505  debug_off();
506  }
507 
508  return(le);
509 }
510 
511 
512 
513 /* Same as above, but with debug control. Used by semantics. */
514 list
516 {
517  list le;
518 
519  debug_on("EFFECTS_DEBUG_LEVEL");
520 
522 
523  debug_off();
524 
525  return(le);
526 }
527 ␌
528 /** computes the proper constant path effects of the input expression
529  using no points-to information.
530 
531  dereferencing paths are currently changed to anywhere effects
532  */
533 list
535 {
536  list le;
537  bool context_stack_defined_p =
539 
540  // needed because it can be called from phases that already define
541  // these variables
542  bool saved_constant_paths_p = get_constant_paths_p();
543  pointer_info_val saved_pointer_info_kind = get_pointer_info_kind();
544 
545  if (! c_module_p(get_current_module_entity()) || !get_bool_property("CONSTANT_PATH_EFFECTS"))
546  set_constant_paths_p(false);
547  else
548  set_constant_paths_p(true);
550 
551  if (!context_stack_defined_p)
552  {
555  }
556 
557  debug_on("PROPER_EFFECTS_DEBUG_LEVEL");
558 
560 
561  if(lhs_p)
563  else
565 
566  if (get_constant_paths_p())
567  {
568  list l_tmp = le;
570  effects_free(l_tmp);
571  }
572 
574  if (!context_stack_defined_p)
575  {
577  }
578  debug_off();
579 
580  set_constant_paths_p(saved_constant_paths_p);
581  set_pointer_info_kind(saved_pointer_info_kind);
582  return(le);
583 }
584 
585 /* For a right hand side expression */
587 {
589 }
590 
591 /* For a left hand side expression */
593 {
595 }
596 
597 
598 /* Same as above, but with some more debug control. Used by semantics.
599  *
600  * FI: What has to be initialized? I end up with functional pointer
601  * reference_to_effect_func unitialized, i.e. 0.
602  *
603  * Use set_methods_for_simple_effects() and
604  * generic_effects_reset_all_methods()
605  */
607 {
608  list le;
609 
610  debug_on("EFFECTS_DEBUG_LEVEL");
611 
613 
614  debug_off();
615 
616  return(le);
617 }
618 
620 {
621  list le;
622 
623  debug_on("EFFECTS_DEBUG_LEVEL");
624 
626 
627  debug_off();
628 
629  return(le);
630 }
631 ␌
633 {
635  bool side_effect_p = false;
636  FOREACH(EFFECT, ef, efl) {
637  if(effect_write_p(ef)) {
638  side_effect_p = true;
639  break;
640  }
641  }
642  gen_free_list(efl);
643  return side_effect_p;
644 }
645 
646 /** computes the proper constant path effects of the input expression
647  using the points-to information of the input statement.
648 
649  set_pt_to_list( (statement_points_to)
650  db_get_memory_resource(DBR_POINTS_TO_LIST, module_name, true) );
651  must have been executed before calling this function for the first time
652 
653  and reset_pt_to_list() must be called after all the calls have been performed.
654  */
655 list
657 {
658  list le;
659  bool context_stack_defined_p =
661  bool stmt_stack_defined_p =
663 
664  // needed because it can be called from phases that already define
665  // these variables
666  bool saved_constant_paths_p = get_constant_paths_p();
667  pointer_info_val saved_pointer_info_kind = get_pointer_info_kind();
668  set_constant_paths_p(true);
670 
671  if (!context_stack_defined_p)
672  {
675  }
676 
677  if (!stmt_stack_defined_p)
679  debug_on("PROPER_EFFECTS_DEBUG_LEVEL");
680 
684 
685  list l_tmp = le;
687  effects_free(l_tmp);
688 
691  if (!context_stack_defined_p)
692  {
694  }
695  if (!stmt_stack_defined_p)
696  {
698  }
699  debug_off();
700  set_constant_paths_p(saved_constant_paths_p);
701  set_pointer_info_kind(saved_pointer_info_kind);
702 
703  return(le);
704 }
705 
706 
707 
708 /* Same as above, but with debug control. Used by semantics. */
709 list
711 {
712  list le;
713 
714  debug_on("EFFECTS_DEBUG_LEVEL");
715 
717 
718  debug_off();
719 
720  return(le);
721 }
722 
723 
724 
725 /* list proper_effects_of_range(range r)
726  * input : an expression and the current context
727  * output : the correpsonding list of effects.
728  * modifies : nothing.
729  * comment :
730  */
731 list
733 {
734  list le;
735  bool context_stack_defined_p =
737 
738  if (!context_stack_defined_p)
739  {
742  }
744 
747 
748  if (!context_stack_defined_p)
749  {
751  }
752 
753  return(le);
754 }
755 
757 {
759  list cee = list_undefined;
760  list cel = list_undefined;
761  bool invariant_p = true;
762 
763  for(cee=ee; !ENDP(cee) && invariant_p; POP(cee)) {
764  effect exp_e = EFFECT(CAR(cee));
765  //reference exp_r = effect_any_reference(exp_e);
766  //entity exp_v = reference_variable(exp_r);
767 
768  for(cel=el; !ENDP(el) && invariant_p; POP(el)) {
769  effect l_e = EFFECT(CAR(cel));
770  action l_a = effect_action(l_e);
771 
772  if(action_write_p(l_a)) {
773  //reference l_r = effect_any_reference(l_e);
774  //entity l_v = reference_variable(l_r);
775 
776  if(effects_interfere_p(l_e,exp_e)) {
777  invariant_p = false;
778  }
779  }
780  }
781  }
782  return invariant_p;
783 }
784 
785 
786 /*************************************************** BACKWARD COMPATIBILITY */
787 
788 /* called from prettyprint CRAY */
789 void
791 {
794  return;
795 }
796 
797 void
799 {
802 
805 
808 }
809 
810 /* called from rice */
811 list
813 {
814  list l_eff;
815 
817  init_rw_effects();
820 
821  debug_on("EFFECTS_DEBUG_LEVEL");
822  pips_debug(1, "begin\n");
823 
828  l_eff = effects_dup(load_rw_effects_list(s));
829 
830  pips_debug(1, "end\n");
831  debug_off();
832 
833  /* Faudrait faire les free, mais je ne sais pas comment. mail a` fc */
839 
840  return l_eff;
841 }
842 
843 /* SIDE EFFECT: set both proper_rw_effects and expr_prw_effects.
844  */
846 {
847  bool ok = true;
851  return ok;
852 }
853 
854 // NL: Does this function really used?
856 {
857  bool ok = true;
859 
860  // functions that can be pointed by effects_computation_init_func:
861  // effects_computation_no_init
862  // init_convex_in_out_regions
863  // init_convex_rw_regions
864  (*effects_computation_init_func)(module_name);
865 
866  /* We also need the proper effects of the module */
867  /*
868  set_proper_rw_effects((*db_get_proper_rw_effects_func)(module_name));
869  */
870 
871  /* Compute the rw effects or references of the module. */
872  init_rw_effects();
875 
876  debug_on("EFFECTS_DEBUG_LEVEL");
877  pips_debug(1, "begin\n");
878 
880 
881  pips_debug(1, "end\n");
882  debug_off();
883 
884  (*db_put_rw_effects_func)(module_name, get_rw_effects());
885  (*db_put_invariant_rw_effects_func)(module_name, get_invariant_rw_effects());
886 
887  // functions that can be pointed by effects_computation_reset_func:
888  // effects_computation_no_reset
889  // reset_convex_in_out_regions
890  // reset_convex_rw_regions
891  (*effects_computation_reset_func)(module_name);
892 
894 
895  //or close??
896 // reset_rw_effects();
897 // reset_invariant_rw_effects();
899  return ok;
900 }
901 
902 
903 
904 /*********** INTERFACES FOR LIVENESS ANALYSIS */
905 
906 
907 bool live_paths(const string module_name)
908 {
909  bool ok;
911  || !get_bool_property("CONSTANT_PATH_EFFECTS"))
912  set_constant_paths_p(false);
913  else
914  set_constant_paths_p(true);
919  return ok;
920 }
921 
922 bool live_in_summary_paths(const string module_name)
923 {
924  bool ok;
926  || !get_bool_property("CONSTANT_PATH_EFFECTS"))
927  set_constant_paths_p(false);
928  else
929  set_constant_paths_p(true);
933  return ok;
934 }
935 
936 bool live_out_summary_paths(const string module_name)
937 {
938  bool ok;
940  || !get_bool_property("CONSTANT_PATH_EFFECTS"))
941  set_constant_paths_p(false);
942  else
943  set_constant_paths_p(true);
948  return ok;
949 }
950 
951 bool print_code_live_in_paths(const string module_name)
952 {
953  return print_code_effects(module_name, act_live_in, false, true,
954  DBR_LIVE_IN_PATHS, DBR_LIVE_IN_SUMMARY_PATHS, ".live_in");
955 }
956 
957 bool print_code_live_out_paths(const string module_name)
958 {
959  return print_code_effects(module_name, act_live_out, false, true,
960  DBR_LIVE_OUT_PATHS, DBR_LIVE_OUT_SUMMARY_PATHS, ".live_out");
961 }
962 
963 // moved here from transformation
964 
965 /**
966  @brief update the input loop loop_locals by removing entities
967  with no corresponding effects in loop body (e.g. entities
968  already private in inner loops and not used in other
969  statements of the current loop body).
970  @param l is the loop to operate one
971  @param changed track if the list have been changed
972  */
973 static void update_loop_locals(loop l, bool *changed)
974 {
975  statement body = loop_body(l);
976  list body_effects = load_rw_effects_list(body);
977  ifdebug(1) {
978  fprintf(stderr, "new body effects:\n");
979  print_effects(body_effects);
980  }
981  list new_loop_locals = NIL;
982  FOREACH(ENTITY, private_variable, loop_locals(l)) {
983  pips_debug(1, "considering entity %s\n",
984  entity_local_name(private_variable));
986  body_effects, private_variable)) {
987  pips_debug(1, "keeping entity\n");
988  new_loop_locals = CONS(ENTITY, private_variable, new_loop_locals);
989  } else {
990  // This is a change :)
991  *changed = true;
992  }
993  }
994 
996  loop_locals(l) = new_loop_locals;
997  ifdebug(1) {
999  fprintf(stderr, "\n");
1000  }
1001 }
1002 
1003 
1004 /**
1005  @brief update loop_locals found by privatize_module by taking parallel loops
1006  into account
1007  */
1008 bool update_loops_locals(const char* module_name, statement module_stat)
1009 {
1011  init_rw_effects();
1015 
1016  debug_on("EFFECTS_DEBUG_LEVEL");
1017  pips_debug(1, "begin\n");
1018 
1020  !get_bool_property("CONSTANT_PATH_EFFECTS"))
1021  set_constant_paths_p(false);
1022  else
1023  set_constant_paths_p(true);
1024  // should use current pointer information
1025  // according to current effects active phase
1027 
1031  rw_effects_of_module_statement(module_stat);
1032 
1033  bool changed = false; // Keep track of a change
1034  gen_context_recurse(module_stat, &changed,
1035  loop_domain, gen_true2, update_loop_locals);
1036 
1037  pips_debug(1, "end, %s\n",
1038  (changed) ? "There was at least a change":
1039  "There was no change at all");
1040  debug_off();
1041 
1042  /* Hope that these close actually free the effects in the mappings */
1044  close_rw_effects();
1049 
1050  return changed;
1051 }
1052 
1053 /* expression_implied_do_index_p
1054  return true if the given entity is the index of an implied do
1055  contained in the given expression. --DB
1056 */
1057 static bool expression_implied_do_index_p(expression exp, entity e)
1058 {
1059  bool li=false;
1060  bool dep=false;
1061 
1064  expression arg1 = EXPRESSION(CAR(args)); /* loop index */
1065  expression arg2 = EXPRESSION(CAR(CDR(args))); /* loop range */
1068  list range_effects;
1069 
1070  pips_debug(5, "begin\n");
1071  pips_debug(7, "%s implied do index ? index: %s\n",
1072  entity_name(e),entity_name(index));
1073 
1074  range_effects = proper_effects_of_range(r);
1075 
1076  FOREACH(EFFECT, eff, range_effects) {
1077  if (reference_variable(effect_any_reference(eff)) == e &&
1078  action_read_p(effect_action(eff))) {
1079  pips_debug(7, "index read in range expressions\n");
1080  dep=true;
1081  }
1082  free_effect(eff);
1083  }
1084  gen_free_list(range_effects);
1085 
1086  if (!dep) {
1087  if (same_entity_p(e,index))
1088  li=true;
1089  else {
1090  FOREACH(EXPRESSION,expr, CDR(CDR(args))) {
1091  syntax s = expression_syntax(expr);
1092  if(syntax_call_p(s)) {
1093  pips_debug(5,"Nested implied do\n");
1094  if (expression_implied_do_index_p(expr,e))
1095  li=true;
1096  }
1097  }
1098  }
1099  }
1100  pips_debug(5,"end\n");
1101  }
1102  return li;
1103 }
1104 
1105 /* is_implied_do_index
1106  returns true if the given entity is the index of one of the
1107  implied do loops of the given instruction. --DB
1108 */
1110 {
1111  bool li = false;
1112 
1113  if (instruction_call_p(ins))
1114  MAP(EXPRESSION,exp, {
1115  if (expression_implied_do_index_p(exp,e)) li=true;
1116  }, call_arguments( instruction_call( ins ) ));
1117 
1118  pips_debug(5, "entity name=%s answer=%s", entity_name(e), bool_to_string(li));
1119 
1120  return li;
1121 }
1122 
1123 /************************************************************** USED BY ICFG */
1124 
1125 #include "pipsdbm.h"
1126 #include "text-util.h"
1127 
1128 // copied/moved from icfg-local.h
1129 #define ADD_ELEMENT_TO_LIST( _list, _type, _element) \
1130  (_list = gen_nconc( _list, CONS( _type, _element, NIL)))
1131 
1132 #define READ_ALL 0
1133 #define WRITE_ALL 1
1134 #define READWRITE_ALL 2
1135 #define READ_END 3
1136 #define WRITE_END 4
1137 #define READWRITE_END 5
1138 
1139 static text safe_statement_to_text(statement s)
1140 {
1141  text t;
1143  t = statement_to_text(s);
1145  return t;
1146 }
1147 
1148 // function also used by ricedg/trace.c
1149 list /* of entity */ get_list_of_variable_to_filter(void)
1150 {
1151  list l = NIL;
1152  string variables_names =
1153  strdup(get_string_property("EFFECTS_FILTER_ON_VARIABLE"));
1154  string saved = variables_names, s;
1155  entity var = NULL;
1156 
1157  for (s = variables_names; *s; s++) {
1158  if (*s == ',') {
1159  *s = '\0';
1160  var = gen_find_tabulated(variables_names, entity_domain);
1161 
1162  if (!var || entity_undefined_p(var))
1163  pips_user_warning("reference variable '%s' not found\n",
1164  variables_names);
1165  else
1166  ADD_ELEMENT_TO_LIST(l, ENTITY, var);
1167  *s = ',';
1168  variables_names = s+1;
1169  }
1170  }
1171 
1172  var = gen_find_tabulated(variables_names, entity_domain);
1173 
1174  if (!var || entity_undefined_p(var))
1175  pips_user_warning("reference variable '%s' not found\n", variables_names);
1176  else
1177  ADD_ELEMENT_TO_LIST(l, ENTITY, var);
1178 
1179  free(saved);
1180  saved = NULL;
1181 
1182  return l;
1183 }
1184 
1185 static list /* of effect */
1186 effects_filter(list l_effs, list l_ents)
1187 {
1188  list l_flt = NIL;
1189 
1190  FOREACH(EFFECT, eff, l_effs)
1191  {
1192  action ac = effect_action(eff);
1194  entity ent = reference_variable(ref);
1195  FOREACH(ENTITY, e_flt, l_ents)
1196  {
1197  if (entities_may_conflict_p(e_flt, ent)) {
1198  bool found = false;
1199  switch(get_int_property("RW_FILTERED_EFFECTS")) {
1200  case READ_ALL:
1201  case READ_END:
1202  if (action_read_p(ac)) {
1203  ADD_ELEMENT_TO_LIST(l_flt, EFFECT, eff);
1204  found = true;
1205  }
1206  break;
1207  case WRITE_ALL:
1208  case WRITE_END:
1209  if (!action_read_p(ac)) {
1210  ADD_ELEMENT_TO_LIST(l_flt, EFFECT, eff);
1211  found = true;
1212  }
1213  break;
1214  case READWRITE_ALL:
1215  case READWRITE_END:
1216  default:
1217  ADD_ELEMENT_TO_LIST(l_flt, EFFECT, eff);
1218  found = true;
1219  break;
1220  }
1221  if (found) break;
1222  }
1223  }
1224  }
1225 
1226  return l_flt;
1227 }
1228 
1229 static text get_statement_filtered_proper_effects(entity caller, statement s)
1230 {
1231  const string caller_name = (const string) module_local_name(caller);
1233  db_get_memory_resource(DBR_PROPER_EFFECTS, caller_name, true);
1234  text t = make_text (NIL);
1235 
1237  list l_effs_flt;
1238  list vars_to_filter = get_list_of_variable_to_filter();
1239  l_effs_flt = effects_filter(l_effs, vars_to_filter);
1240  gen_free_list(vars_to_filter);
1241 
1242  if (l_effs_flt != NIL) {
1244 
1245  // do not display comments in the decoration
1246  // ??? WHOOPS this actually remove the comments?
1248  statement_comments(s)[0] = '\0';
1249 
1250  if (instruction_call_p(i)) {
1252  entity e_callee = call_function(callee);
1253 
1254  /* the real function is processed in call_flt */
1255  if (!value_code_p(entity_initial(e_callee))) {
1256  MERGE_TEXTS(t, simple_rw_effects_to_text(l_effs_flt));
1257  MERGE_TEXTS(t, safe_statement_to_text(s));
1258  }
1259  } else {
1260  MERGE_TEXTS(t, simple_rw_effects_to_text(l_effs_flt));
1261  MERGE_TEXTS(t, safe_statement_to_text(s));
1262  }
1263  }
1264 
1265  return t;
1266 }
1267 
1268 /* used by icfg
1269  */
1270 static text get_real_call_filtered_proper_effects(
1271  entity e_caller, // who is doing the call
1272  statement s, // the containing statement
1273  call c) // a call within this statement
1274 {
1275  text t = make_text(NIL);
1276 
1277  const char* caller_name = module_local_name(e_caller);
1279  db_get_memory_resource(DBR_PROPER_EFFECTS, caller_name, true);
1280 
1282  list l_effs_flt;
1283  list vars_to_filter = get_list_of_variable_to_filter();
1284  l_effs_flt = effects_filter(l_effs, vars_to_filter);
1285 
1286  if (l_effs_flt != NIL) {
1287 
1288  if (get_int_property("RW_FILTERED_EFFECTS") < READ_END) {
1289  //print the effects before all procedures
1290  MERGE_TEXTS(t, simple_rw_effects_to_text(l_effs_flt));
1291  MERGE_TEXTS(t, safe_statement_to_text(s));
1292  } else {
1293  //print the effects before only the last procedure
1295  {
1296  syntax syn = expression_syntax(exp);
1297 
1298  if (syntax_reference_p(syn)) {
1300 
1301  FOREACH(ENTITY, e, vars_to_filter)
1302  {
1303  if (entities_may_conflict_p(e, var)) {
1304  MERGE_TEXTS(t, simple_rw_effects_to_text(l_effs_flt));
1305  MERGE_TEXTS(t, safe_statement_to_text(s));
1306  break;
1307  }
1308  }
1309  }
1310  }
1311  }
1312  }
1313  gen_free_list(vars_to_filter);
1314 
1315  return t;
1316 }
1317 
1318 
1319 /********************************************************************** ICFG */
1320 
1321 #include "pips-libs.h"
1322 #ifdef HAVE_PIPS_icfg_LIBRARY
1323 #include "icfg.h"
1324 
1326 {
1327  return generic_print_icfg(module_name, false, false, false,
1329 }
1330 
1332 {
1333  return generic_print_icfg(module_name, false, false, false,
1335 }
1336 
1338 {
1339  return generic_print_icfg(module_name, false, true, false,
1341 }
1342 
1344 {
1345  return generic_print_icfg(module_name, false, true, false,
1347 }
1348 
1350 {
1351  return generic_print_icfg(module_name, true, true, false,
1353 }
1354 
1356 {
1357  return generic_print_icfg(module_name, true, true, false,
1359 }
1360 
1362 {
1363  return generic_print_icfg_filtered(module_name, false, false, false,
1364  get_real_call_filtered_proper_effects,
1365  get_statement_filtered_proper_effects);
1366 }
1367 
1369 {
1370  return generic_print_icfg_filtered(module_name, false, false, true,
1371  get_real_call_filtered_proper_effects,
1372  get_statement_filtered_proper_effects);
1373 }
1374 
1375 #endif // HAVE_PIPS_icfg_LIBRARY
int get_int_property(const string)
void free_effect(effect p)
Definition: effects.c:451
effects apply_statement_effects(statement_effects f, statement k)
Definition: effects.c:1007
text make_text(list a)
Definition: text.c:107
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
static const char * caller_name
Definition: alias_check.c:122
static entity callee
Definition: alias_pairs.c:62
static bool is_user_view
useful
#define resource_name(x)
Definition: database.h:108
@ with_points_to
@ with_no_pointer_info
@ with_pointer_values
void free_effects_private_current_context_stack(void)
void reset_useful_variables_effects(void)
void set_is_user_view_p(bool)
bool live_out_summary_paths_engine(const char *)
bool live_in_summary_paths_engine(const char *)
liveness_analysis_engine.c
void make_effects_private_current_context_stack(void)
void make_effects_private_current_stmt_stack(void)
utils.c
bool in_effects_engine(const char *, effects_representation_val)
list generic_proper_effects_of_range(range)
pointer_info_val get_pointer_info_kind(void)
void expression_proper_effects_engine(const char *, statement)
void proper_effects_of_module_statement(statement)
void close_invariant_rw_effects(void)
bool out_effects_engine(const char *, effects_representation_val)
bool summary_in_effects_engine(const char *)
in_effects_engine.c
void close_rw_effects(void)
void init_useful_variables_effects(void)
list generic_proper_effects_of_any_lhs(expression)
void init_rw_effects(void)
statement effects_private_current_stmt_pop(void)
text get_any_effect_type_text(const char *, string, string, bool)
void free_effects_private_current_stmt_stack(void)
void rw_effects_of_module_statement(statement)
void init_proper_rw_effects(void)
void effects_free(list)
bool effects_private_current_context_stack_initialized_p(void)
bool live_paths_engine(const char *, effects_representation_val)
bool summary_out_effects_engine(const char *)
void effects_private_current_stmt_push(statement)
bool summary_rw_effects_engine(const char *)
list effects_dup(list)
bool rw_effects_engine(const char *)
list load_rw_effects_list(statement)
bool get_constant_paths_p(void)
statement_effects get_rw_effects(void)
void set_prettyprint_with_attachments(bool)
list generic_proper_effects_of_expression(expression)
void init_invariant_rw_effects(void)
transformer effects_private_current_context_pop(void)
void generic_effects_reset_all_methods(void)
void close_useful_variables_effects(void)
void set_pointer_info_kind(pointer_info_val)
methods.c
void effects_private_current_context_push(transformer)
list pointer_effects_to_constant_path_effects(list)
bool proper_effects_engine(const char *)
bool print_source_or_code_with_any_effects_engine(const char *, string, string, string, bool)
void set_constant_paths_p(bool)
bool effects_private_current_stmt_stack_initialized_p(void)
statement_effects get_invariant_rw_effects(void)
void close_proper_rw_effects(void)
simple_effects_actions_interpretations
actions interpretation for simple effects prettyprinting
@ act_inout
@ act_live_out
@ act_live_in
bool print_source_in_effects(const string)
bool print_icfg_with_proper_effects(const string)
void reset_methods_for_inout_effects(void)
void set_methods_for_proper_simple_effects(void)
bool cumulated_effects(const string)
bool proper_pointer_effects(const string)
bool proper_references(const string)
bool summary_effects(const string)
bool print_code_cumulated_effects(const string)
bool expression_invariant_wrt_effects(expression, list)
list proper_constant_path_effects_of_lhs_expression(expression)
bool live_in_summary_paths(const string)
void set_methods_for_inout_effects(const char *)
text simple_rw_effects_to_text(list)
prettyprint.c
bool in_effects(const string)
text get_text_proper_effects(const string)
bool live_paths(const string)
void set_methods_for_proper_simple_pointer_effects(void)
bool cumulated_pointer_effects_with_points_to(const string)
list proper_constant_path_effects_of_expression(expression)
bool print_code_as_a_graph_cumulated_effects(const string)
bool cumulated_pointer_effects_with_pointer_values(const string)
text get_text_proper_pointer_effects(const string)
bool proper_effects_with_pointer_values(const string)
list proper_constant_path_effects_of_any_expression(expression, bool)
bool print_icfg_with_loops_proper_effects(const string)
bool out_effects(const string)
bool print_code_proper_pointer_effects(const string)
bool update_loops_locals(const char *, statement)
list proper_effects_of_expression(expression)
bool simple_cumulated_effects(const char *, statement)
bool print_source_out_effects(const string)
bool print_icfg_with_filtered_proper_effects(const string)
text get_text_cumulated_effects(const string)
bool cumulated_pointer_effects(const string)
list expression_to_proper_effects(expression)
bool print_code_proper_effects(const string)
bool proper_effects_with_points_to(const string)
bool print_icfg_with_loops_cumulated_effects(const string)
bool print_source_proper_effects(const string)
bool print_code_live_in_paths(const string)
bool proper_effects(const string)
bool print_code_out_effects(const string)
bool print_code_in_effects(const string)
bool live_out_summary_paths(const string)
bool print_code_cumulated_pointer_effects(const string)
bool cumulated_effects_with_pointer_values(const string)
list expression_to_proper_constant_path_effects(expression)
bool in_summary_effects(const string)
void set_methods_for_proper_references(void)
methods.c
text get_text_cumulated_pointer_effects(const string)
bool print_code_cumulated_references(const string)
list statement_to_effects(statement)
void rproper_effects_of_statement(statement)
void set_methods_for_live_in_paths_prettyprint(const char *)
void set_methods_for_simple_pointer_effects(void)
list proper_effects_of_range(range)
list get_list_of_variable_to_filter(void)
bool print_code_proper_references(const string)
void reset_methods_for_effects_prettyprint(const char *)
bool print_code_as_a_graph_proper_effects(const string)
void set_methods_for_cumulated_references(void)
list lhs_expression_to_proper_constant_path_effects(expression)
bool print_source_cumulated_effects(const string)
void set_methods_for_simple_effects(void)
bool is_implied_do_index(entity, instruction)
bool cumulated_references(const string)
interface.c
bool summary_pointer_effects(const string)
bool print_dvicfg_with_filtered_proper_effects(const string)
void set_methods_for_live_paths(const char *)
void rcumulated_effects_of_statement(statement)
bool cumulated_effects_with_points_to(const string)
void set_methods_for_live_out_paths_prettyprint(const char *)
list proper_constant_path_effects_of_expression_with_points_to(expression, statement)
bool print_icfg_with_control_proper_effects(const string)
void set_methods_for_rw_effects_prettyprint(const char *)
bool print_icfg_with_control_cumulated_effects(const string)
bool print_code_live_out_paths(const string)
bool out_summary_effects(const string)
bool expression_with_side_effect_p(expression)
bool print_icfg_with_cumulated_effects(const string)
bool full_simple_proper_effects(const char *, statement)
void set_methods_for_inout_effects_prettyprint(const char *)
list expression_to_proper_constant_path_effects_with_points_to(expression, statement)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define effect_write_p(eff)
bool effects_interfere_p(effect, effect)
Two effects interfere if one of them modify the set of locations defined by the other one.
Definition: effects.c:714
#define effect_action(x)
Definition: effects.h:642
#define action_write_p(x)
Definition: effects.h:314
struct _newgen_struct_statement_effects_ * statement_effects
Definition: effects.h:210
#define action_read_p(x)
Definition: effects.h:311
#define effects_effects(x)
Definition: effects.h:710
#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
char * get_string_property(const char *)
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 free(void *)
bool success
Definition: gpips-local.h:59
bool entities_may_conflict_p(entity e1, entity e2)
Check if two entities may conflict.
Definition: conflicts.c:984
bool effects_may_read_or_write_memory_paths_from_entity_p(list l_eff, entity e)
tests whether the input effects list may contain effects with a memory path from the input entity e; ...
Definition: conflicts.c:1130
void reset_current_module_entity(void)
Reset the current module entity.
Definition: static.c:97
void reset_current_module_statement(void)
Reset the current module statement.
Definition: static.c:221
statement set_current_module_statement(statement)
Set the current module statement.
Definition: static.c:165
entity set_current_module_entity(entity)
static.c
Definition: static.c:66
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
bool gen_true2(__attribute__((unused)) gen_chunk *u1, __attribute__((unused)) void *u2)
Definition: genClib.c:2785
#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
#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 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 ADD_ELEMENT_TO_LIST(_list, _type, _element)
Definition: icfg-local.h:50
bool generic_print_icfg(const string, bool, bool, bool, text(*)(const string))
Definition: icfg_scan.c:713
bool generic_print_icfg_filtered(const string, bool, bool, bool, text(*)(entity, statement, call), text(*)(entity, statement))
Definition: icfg_scan.c:735
#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
string bool_to_string(bool)
Definition: string.c:243
void * gen_find_tabulated(const char *, int)
Definition: tabulated.c:218
#define string_undefined
Definition: newgen_types.h:40
char * string
STRING.
Definition: newgen_types.h:39
#define string_undefined_p(s)
Definition: newgen_types.h:41
#define print_effects(e)
Definition: print.c:334
text statement_to_text(statement)
Definition: statement.c:124
void set_bool_property(const char *, bool)
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
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
void print_entities(list l)
Definition: entity.c:167
bool expression_implied_do_p(e)
Definition: expression.c:817
#define loop_body(x)
Definition: ri.h:1644
#define value_code_p(x)
Definition: ri.h:3065
#define syntax_reference_p(x)
Definition: ri.h:2728
#define transformer_undefined
Definition: ri.h:2847
#define syntax_reference(x)
Definition: ri.h:2730
#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 ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define syntax_call_p(x)
Definition: ri.h:2734
#define syntax_range(x)
Definition: ri.h:2733
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define entity_undefined_p(x)
Definition: ri.h:2762
#define entity_name(x)
Definition: ri.h:2790
#define syntax_call(x)
Definition: ri.h:2736
#define instruction_call_p(x)
Definition: ri.h:1527
#define loop_locals(x)
Definition: ri.h:1650
#define statement_instruction(x)
Definition: ri.h:2458
#define statement_comments(x)
Definition: ri.h:2456
#define instruction_call(x)
Definition: ri.h:1529
#define call_arguments(x)
Definition: ri.h:711
#define expression_syntax(x)
Definition: ri.h:1247
#define entity_domain
newgen_syntax_domain_defined
Definition: ri.h:410
#define entity_initial(x)
Definition: ri.h:2796
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
#define ifdebug(n)
Definition: sg.c:47
static bool ok
static size_t current
Definition: string.c:115
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
Definition: statement.c:54
#define MERGE_TEXTS(r, t)
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207