PIPS
icm.c
Go to the documentation of this file.
1 /*
2 
3  $Id: icm.c 23065 2016-03-02 09:05:50Z 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 /*
28  * Invariant Code Motion
29  *
30  * Olivier Albiez
31  */
32 
33 
34 /*
35  * Il faut tester la presence de dependance sur le graphe original et
36  * modifier une copie.
37  */
38 
39 
40 #include "local.h"
41 #include "prettyprint.h" // for debugging
42 #include "effects-generic.h"
43 #include "effects-simple.h"
44 
46 
47 
48 /* Set to 2 if we want to simplify in two passes */
49 #define NB_SIMPLIFY_PASSES 1
50 
51 
52 #define FLOW_DEPENDANCE 1
53 #define ANTI_DEPENDANCE 2
54 #define OUTPUT_DEPENDANCE 4
55 #define INPUT_DEPENDANCE 8
56 #define ALL_DEPENDANCES (FLOW_DEPENDANCE|ANTI_DEPENDANCE|OUTPUT_DEPENDANCE)
57 
58 /*
59  * Definition of local variables
60  */
61 static int reference_level=0;
62 
63 static bool expression_invariant = false;
64 static set /* of entity */ invariant_entities = set_undefined;
65 //static set /* of statement */ statements_partialy_invariant = set_undefined;
66 
67 
68 /*********************************************************** PRINT FUNCTIONS */
69 
70 
71 /*
72  * Print a statement_to_effect table.
73  */
74 void
76 {
77  fprintf(stderr, "\n");
78  STATEMENT_EFFECTS_MAP(s, e, {
79  fprintf(stderr,
80  "%02td (%p) -> (%td) : ",
81  statement_number(s),
82  s,
84 
85  MAP(EFFECT, e, {
86  print_words(stderr, words_effect(e));
87  fprintf(stderr, "(%p), ", e);
88  }, effects_effects(e));
89 
90  fprintf(stderr, "\n");
91  }, se);
92 }
93 
94 
95 /*
96  * Print a conflict.
97  */
98 static void
100 {
101  fprintf(fd, "\t\tfrom ");
103 
104  fprintf(fd, " to ");
106 
107  fprintf(fd, " at levels ");
108  MAP(INT, level, {
109  fprintf(fd, " %d", level);
110  }, cone_levels(conflict_cone(c)));
111  fprintf(fd, "\n");
112 }
113 
114 
115 /*
116  * Print a successor.
117  */
118 static void
120 {
121  vertex v = successor_vertex(su);
122  fprintf(fd,
123  "link with %02td :\n",
125 
126  MAP(CONFLICT, c, {
127  prettyprint_conflict(fd, c);
129 }
130 
131 
132 /*
133  * Print a vertex.
134  */
135 static void
137 {
138  fprintf(fd,
139  "vertex %02td :\n",
141  MAP(SUCCESSOR, s, {
142  prettyprint_successor(fd, s);
143  }, vertex_successors(v));
144 }
145 
146 
147 /*
148  * Print a entities list.
149  */
150 void
151 print_list_entities(list /* of entity */ l)
152 {
153  MAP(ENTITY, e, {
154  fprintf(stderr, "%s ", entity_name(e));
155  }, l);
156 }
157 
158 
159 /*********************************************************** MISC FUNCTIONS */
160 
161 
162 /*
163  * Add statements from the vertex list to the statements set.
164  */
165 static set /* of statement */
166 vertices_to_statements(list /* of vertex */ vl,
167  set /* of statement */ss)
168 {
169  MAP(VERTEX, v, {
170  ss = set_add_element(ss, ss, (char *) vertex_to_statement(v));
171  }, vl);
172 
173  return ss;
174 }
175 
176 
177 static set /* of entity */
179  set /* of entity */ rs)
180 {
182  list /* of effect */ le = load_proper_rw_effects_list(st);
183 
184  MAP(EFFECT, ef, {
185  if (effect_write_p(ef)) {
187 
188  if (!set_belong_p(rs, (char *) v)) {
189  rs = set_add_element(rs, rs, (char *) e);
190  }
191  }
192  }, le);
193 
194  return rs;
195 }
196 
197 
198 /************************************************************ MAPPING TOOLS */
199 
200 
202 GENERIC_LOCAL_MAPPING(has_indices, list, statement)
203 
204 static list indices = NIL;
205 static int depth = 0;
206 
207 
208 /*
209  * Gen_multi_recurse hook.
210  * Set the depth and the indices list of the statement.
211  */
212 static bool
214 {
215  store_has_level(s, depth);
216  store_statement_has_indices(s, gen_nreverse(gen_copy_seq(indices)));
217 
218  return true;
219 }
220 
221 
222 /*
223  * Gen_multi_recurse hook.
224  * Update the depth and the indices list when enter a loop.
225  */
226 static bool
228 {
229  entity index = loop_index(l);
230  indices = CONS(ENTITY, index, indices);
231  ++depth;
232 
233  return true;
234 }
235 
236 
237 /*
238  * Gen_multi_recurse hook.
239  * Update the depth and the indices list when exit a loop.
240  */
241 static void
243 {
244  list new_indices = CDR(indices);
245  free(indices);
246  indices = new_indices;
247  --depth;
248 }
249 
250 
251 /***************************************************** DEPENDANCES FUNCTIONS */
252 
253 
254 /*
255  * Test if the conflict correspond to the given dependance type.
256  */
257 static bool
258 action_dependance_p(conflict c, int dependance_type)
259 {
262 
263  return (((dependance_type & FLOW_DEPENDANCE) &&
264  ((action_write_p(s) && action_read_p(k)))) ||
265  ((dependance_type & ANTI_DEPENDANCE) &&
266  ((action_read_p(s) && action_write_p(k)))) ||
267  ((dependance_type & OUTPUT_DEPENDANCE) &&
268  ((action_write_p(s) && action_write_p(k)))) ||
269  ((dependance_type & INPUT_DEPENDANCE) &&
270  ((action_read_p(s) && action_read_p(k)))));
271 }
272 
273 
274 /*
275  * Test the existence of a given dependence between two vertices v1, v2.
276  *
277  * Note:
278  * - dependance_type is a bitfield which contains the kind of dependence,
279  * - level is the minimum level wanted.
280  */
281 static bool
282 dependance_vertices_p(vertex v1, vertex v2, int dependance_type, int level)
283 {
284  ifdebug(9) {
285  debug(9, "dependance_vertices_p", "");
286 
287  if (dependance_type & FLOW_DEPENDANCE) fprintf(stderr, "F ");
288  if (dependance_type & ANTI_DEPENDANCE) fprintf(stderr, "A ");
289  if (dependance_type & OUTPUT_DEPENDANCE) fprintf(stderr, "O ");
290  if (dependance_type & INPUT_DEPENDANCE) fprintf(stderr, "I ");
291  fprintf(stderr, "dep. at level >= %d ", level);
292  fprintf(stderr,
293  "between %02td and %02td ? ",
296  }
297 
298  MAP(SUCCESSOR, su, {
299  vertex s = successor_vertex(su);
300  if (s == v2) {
301  MAP(CONFLICT, c, {
302  if (conflict_cone(c) != cone_undefined) {
303  MAP(INT, l, {
304  if (l >= level) {
305  if (action_dependance_p(c, dependance_type))
306  {
307  ifdebug(9) { fprintf(stderr, "yes\n"); }
308  return true;
309  }
310  }
311  }, cone_levels(conflict_cone(c)));
312  }
314  }
315  }, vertex_successors(v1));
316 
317  ifdebug(9) { fprintf(stderr, "no\n"); }
318  return false;
319 }
320 
321 
322 /*
323  * Test the existance of a given dependance from the vertex v with any other
324  * vertices than v.
325  */
326 static bool
328  int dependance_type,
329  int level)
330 {
331  MAP(SUCCESSOR, su, {
332  vertex y = successor_vertex(su);
333  if (v != y) {
334  if (dependance_vertices_p(v, y, dependance_type, level))
335  return true;
336  }
337  }, vertex_successors(v));
338 
339  return false;
340 }
341 
342 /*
343  * Remove all levels between level_min and level_max from the list of levels.
344  */
345 static list /* of level */
346 remove_dependance_from_levels(list /* of level */ levels,
347  int level_min,
348  int level_max)
349 {
350  list /* of level */ new_levels = NIL;
351 
352  MAP(INT, level, {
353  if ((level < level_min) || (level > level_max)) {
354  new_levels = gen_nconc(new_levels, CONS(INT, level, NIL));
355  }
356  }, levels);
357 
358  /* memory leak : levels */
359 
360  return new_levels;
361 }
362 
363 
364 /*
365  * Remove all conflicts matching the dependance_type for a level
366  * between level_min and level_max.
367  */
368 static list /* of conflict */
369 remove_dependance_from_conflicts(list /* of conflict */ conflicts,
370  int dependance_type,
371  int level_min,
372  int level_max)
373 {
374  list /* of conflict */ new_conflicts = NIL;
375 
376  ifdebug(7) {
377  fprintf(stderr, "Old conflicts :\n");
378  MAP(CONFLICT, c, {
379  prettyprint_conflict(stderr, c);
380  }, conflicts);
381  }
382 
383  FOREACH(CONFLICT, c, conflicts) {
384  if(conflict_cone(c) != cone_undefined) {
385  if (action_dependance_p(c, dependance_type))
386  {
387  list /* of level */ levels = cone_levels(conflict_cone(c));
388 
389  list /* of level */ new_levels =
391  level_min,
392  level_max);
393 
394  if (new_levels != NIL) {
395  cone_levels(conflict_cone(c)) = new_levels;
396  new_conflicts = CONS(CONFLICT, c, new_conflicts);
397  }
398 
399  /* memory leak : levels */
400  }
401  else {
402  new_conflicts = CONS(CONFLICT, c, new_conflicts);
403  }
404  }
405  else {
406  new_conflicts = CONS(CONFLICT, c, new_conflicts);
407  }
408  }
409 
410  /* memory leak : conflicts */
411 
412  ifdebug(7)
413  {
414  fprintf(stderr, "New conflicts :\n");
415  MAP(CONFLICT, c, {
416  prettyprint_conflict(stderr, c);
417  }, new_conflicts);
418  }
419 
420  return new_conflicts;
421 }
422 
423 
424 /*
425  * Remove all successors matching the given parameters.
426  */
427 static list /* of successor */
429  vertex v2,
430  int dependance_type,
431  int level_min,
432  int level_max)
433 {
434  list /* of successor */ new_successors = NIL;
435 
436  ifdebug(7)
437  {
438  fprintf(stderr, "Old successors :\n");
439  MAP(SUCCESSOR, s, {
440  prettyprint_successor(stderr, s);
441  }, successors);
442  }
443 
444  MAP(SUCCESSOR, su, {
445  vertex v = successor_vertex(su);
446 
447  if (v == v2) {
448  list /* of conflict */ lc =
450 
451  list /* of conflict */ new_lc =
453  dependance_type,
454  level_min,
455  level_max);
456 
457  if (new_lc != NIL) {
459  new_successors = CONS(SUCCESSOR, su, new_successors);
460  }
461 
462  /* memory leak : lc */
463  }
464  else {
465  new_successors = CONS(SUCCESSOR, su, new_successors);
466  }
467 
468  }, successors);
469 
470  /* memory leak : successors */
471 
472  ifdebug(7)
473  {
474  fprintf(stderr, "New successors :\n");
475  MAP(SUCCESSOR, s, {
476  prettyprint_successor(stderr, s);
477  }, successors);
478  }
479 
480  return new_successors;
481 }
482 
483 
484 /*
485  * Remove all dependances between v1 and v2 matching the given parameters.
486  */
487 static void
488 remove_dependance(vertex v1, /* Successors of this vertex are updated */
489  vertex v2,
490  int dependance_type,
491  int level_min,
492  int level_max)
493 {
494  list /* of successor */ v1_successors = vertex_successors(v1);
495 
496  ifdebug(3) {
497  pips_debug(3, "Remove ");
498 
499  if (dependance_type & FLOW_DEPENDANCE) fprintf(stderr, "F ");
500  if (dependance_type & ANTI_DEPENDANCE) fprintf(stderr, "A ");
501  if (dependance_type & OUTPUT_DEPENDANCE) fprintf(stderr, "O ");
502  if (dependance_type & INPUT_DEPENDANCE) fprintf(stderr, "I ");
503 
504  fprintf(stderr,
505  "dep. at level >= %d and level <= %d ",
506  level_min,
507  level_max);
508 
509  fprintf(stderr,
510  "between %02td and %02td.\n",
513  }
514 
515  vertex_successors(v1) =
516  remove_dependances_from_successors(v1_successors,
517  v2,
518  dependance_type,
519  level_min,
520  level_max);
521 
522  ifdebug(7) {
523  prettyprint_vertex(stderr, v1);
524  }
525 }
526 
527 
528 /************************************************************ SCCS FUNCTIONS */
529 
530 
531 /*
532  * FindAndTopSortSccs hook.
533  * Test if the vertex belong to the region.
534  */
535 static bool
537 {
538  return(!set_belong_p(region, (char *) vertex_to_statement(v)));
539 }
540 
541 
542 /*
543  * FindAndTopSortSccs hook.
544  * Test if exist any dependance with a level >= 'level'.
545  */
546 static bool
548  set /* of statement */ region,
549  successor su,
550  int level)
551 {
553  return(true);
554 
555  if (!dependance_vertices_p(v,
556  successor_vertex(su),
558  level))
559  return (true);
560 
561  return false;
562 }
563 
564 
565 /*
566  * FindAndTopSortSccs hook.
567  * Test if exist a flow dependance with a level >= 'level'.
568  */
569 static bool
571  set /* of statement */ region,
572  successor su,
573  int level)
574 {
576  return(true);
577 
578  if (!dependance_vertices_p(v,
579  successor_vertex(su),
581  level))
582  return (true);
583 
584  return (false);
585 }
586 
587 
588 /********************************************************* DG SIMPLIFICATION */
589 
590 
591 /*
592  * Test if a statement depend of any indicies.
593  * The 'level' first indicies are not used.
594  */
595 static bool
597  list /* of entity */ indices,
598  int level)
599 {
600  list /* of effect */ le = load_proper_rw_effects_list(st);
601 
602  ifdebug(6) {
603  pips_debug(6, "Statement %02td depend of ", statement_number(st));
605  }
606 
607  /* Ignore the first indicies... */
608  for(; level > reference_level; --level) {
609  indices = CDR(indices);
610  }
611 
612  MAP(ENTITY, index, {
613  MAP(EFFECT, ef, {
615  if (e == index) {
616 
617  ifdebug(6) {
618  fprintf(stderr,": yes\n");
619  }
620 
621  return true;
622  }
623  }, le);
624  }, indices);
625 
626  ifdebug(6) {
627  fprintf(stderr,": no\n");
628  }
629 
630  return false;
631 }
632 
633 
634 static bool
636 {
639  return true;
640 }
641 
642 static bool ref_flt(reference r)
643 {
645 }
646 
647 static bool
648 expressions_invariant_p(list /* of expression */ le)
649 {
650  MAP(EXPRESSION, exp, {
651  expression_invariant = true;
652 
654 
655  if (!expression_invariant) {
656  return false;
657  }
658  }, le);
659 
660  return true;
661 }
662 
663 
664 /*
665  * Test if the vertex is partially invariant.
666  */
667 static bool
669  __attribute__((unused)) graph g,
670  __attribute__((unused)) int level,
671  __attribute__((unused)) set /* of statement */ invariant)
672 {
674 
675  MAP(EFFECT, ef, {
677 
678  /* Looking for write effects only */
679  if (effect_write_p(ef)) {
680 
681  /* Which kind of reference we have ? */
682  if (reference_indices(ref) != NIL) {
683  /* An array access with well known indices */
685  pips_debug(6,
686  "statement %02td is partially invariant "
687  "(known array access).\n",
688  statement_number(st));
689 
690  return true;
691  }
692  else {
693  pips_debug(6,
694  "statement %02td is not partially invariant "
695  "(known array access).\n",
696  statement_number(st));
697 
698  return false;
699  }
700  }
701  else {
703  /* An array access with unknow indices */
704  pips_debug(6,
705  "statement %02td is not partially invariant "
706  "(UNKNOWN array access).\n",
707  statement_number(st));
708 
709  return false;
710  }
711  else {
712  /* A scalar variable */
713  pips_debug(6,
714  "statement %02td is partially invariant "
715  "(scalar access).\n",
716  statement_number(st));
717 
718  return true;
719  }
720  }
721  }
723 
724  pips_debug(6,
725  "statement %02td is not partially invariant.\n",
726  statement_number(st));
727 
728  return false;
729 }
730 
731 
732 /*
733  * Test if the vertex is invariant.
734  */
735 static bool
737  graph g,
738  int level,
739  set /* of statement */ region,
740  set /* of statement */ invariant)
741 {
743 
744  /* Test if the statement is dependent of ALL loop indexes >= level */
746  load_statement_has_indices(st),
747  level)) {
748  pips_debug(6,
749  "statement %02td is not invariant (depend of indices).\n",
750  statement_number(st));
751 
752  return false;
753  }
754 
755  /* If there is a flow dependence from v to v, then v is not variant */
757  pips_debug(6,
758  "statement %02td is not invariant (self flow dep).\n",
759  statement_number(st));
760 
761  return false;
762  }
763 
764  /* If there is a flow dependence from y to v and if y is not invariant,
765  * then v is not invariant */
766  MAP(VERTEX, y, {
768  statement y_st = vertex_to_statement(y);
769 
770  if (!set_belong_p(invariant, (char *) y_st) &&
771  set_belong_p(region, (char *) y_st)) {
772 
773  pips_debug(6,
774  "statement %02td is not invariant "
775  "(dep. of %02td).\n",
776  statement_number(st),
777  statement_number(y_st));
778 
779  return false;
780  }
781  }
782  }, graph_vertices(g));
783 
784  pips_debug(6,
785  "statement %02td is invariant.\n",
786  statement_number(st));
787 
788  return true;
789 }
790 
791 
792 /*
793  * Simplify a invariant vertex 'v' using the following rule:
794  *
795  * if
796  * exist output(v, v, <= level)
797  * not exist output(v, z, <= level) v != z
798  * then
799  * remove output(v, v, <= level)
800  * foreach y satisfying
801  * exist flow(v -> y, infiny)
802  * exist anti(y -> v, <= level)
803  * do remove anti(y -> v, <= level)
804  */
805 static void
806 SimplifyInvariantVertex(vertex v, /* Successors of this vertex are updated */
807  set /* of statement */ region,
808  int level)
809 {
810  set /* of vertex */ matching_vertices = set_make(set_pointer);
812 
817  vertex y = successor_vertex(su);
821 
822  matching_vertices = set_add_element(matching_vertices,
823  matching_vertices,
824  (char *) y);
825  }
826  }
827 
828  //remove_dependance(v, v, OUTPUT_DEPENDANCE, 0, load_has_level(st));
829  remove_dependance(v, v, OUTPUT_DEPENDANCE, level, load_has_level(st));
830 
831  if (!set_empty_p(matching_vertices)) {
832  SET_MAP(y, {
834  //0, load_has_level(st));
835  level, load_has_level(st));
836  }, matching_vertices);
837  }
838  }
839 
840  set_free(matching_vertices);
841 }
842 
843 
844 /*
845  * Find and simplify invariants statements.
846  */
847 static graph
848 DoInvariantsStatements(list /* of scc */ lsccs,
849  graph g,
850  set /* of statement */ region,
851  int level,
852  set /* of statement */ partially_invariant)
853 {
854  set /* of statement */ invariant = set_make(set_pointer);
855 
856  FOREACH(SCC, s, lsccs) {
857  list /* of vertex */ lv = scc_vertices(s);
858 
859  if (gen_length(lv) > 1) {
860  /* Group of vertices : all are variants */
861  }
862  else {
863  /* One statement... */
864  vertex v = VERTEX(CAR(lv));
866 
867  if (!declaration_statement_p(st)) {
868  if (vertex_invariant_p(v, g, level, region, invariant)) {
869  /* which is invariant */
871 
872  /* Added to the list */
873  invariant = set_add_element(invariant,
874  invariant,
875  (char *) st);
876 
877  /* Invariant is partially invariant... */
878  partially_invariant = set_add_element(partially_invariant,
879  partially_invariant,
880  (char *) st);
881 
885 
886  }
887  else if (vertex_partially_invariant_p(v, g, level, invariant)) {
888  partially_invariant =
889  set_add_element(partially_invariant,
890  partially_invariant,
891  (char *) st);
892  }
893  }
894  else {
895  //If it's an declaration, so we work on environment domain
896  // NL: It's a workaround, and not totally sure that it always work, not enough test case
897 
898  /* NL: I can't explain why we have to add the declaration statement
899  * as an invariant statement, but it's seem that it work,
900  * and permit some optimizations...
901  */
902  /* Added to the list */
903  invariant = set_add_element(invariant,
904  invariant,
905  (char *) st);
906 
907  /* Invariant is partially invariant... */
908  partially_invariant = set_add_element(partially_invariant,
909  partially_invariant,
910  (char *) st);
911 
912  /* NL: I'm not totally sure of the explanation I propose below
913  * The variable declared inside the loop can be consider as invariant variable
914  * because there values only be important inside the loop and not outside.
915  * so from the outside of the loop these variables doesn't exist and
916  * so can be consider as invariant?
917  */
921  }
922  }
923  }
924 
925  set_free(invariant);
926 
927  return g;
928 }
929 
930 
931 /*
932  * Test if the vertex is redundant.
933  */
934 static bool
936  __attribute__((unused)) graph g,
937  int level,
938  set /* of statement */ region,
939  set /* of statement */ partially_invariant,
940  set /* of statement */ redundant)
941 {
943 
944  /* Test if the statement is depandant of ALL loop indexes >= level */
945  /* This condition is not required, but putting a statement depending
946  of indicies after the loop is tiedous (setting the value to
947  the bound+1...) */
948 /*
949  if (statement_depend_of_indices_p(st,
950  load_statement_has_indices(st),
951  level)) {
952  ifdebug(6) {
953  debug(6, "vertex_redundant_p", "");
954  fprintf(stderr,
955  "statement %02d is not redundant (depend of indices).\n",
956  statement_number(st));
957  }
958 
959  return false;
960  }
961 */
962 
963  /* Test if we are not always writing at the same adress
964  ie. is not partially_invariant. */
965  if (!set_belong_p(partially_invariant, (char *) st)) {
966  pips_debug(6,
967  "statement %02td is not redundant (variable address).\n",
968  statement_number(st));
969 
970  return false;
971  }
972 
973  /* If there is a flow dependance from v to y and if y is not redundant,
974  then v is not redundant */
976  vertex y = successor_vertex(su);
978  statement y_st = vertex_to_statement(y);
979 
980  if (!set_belong_p(redundant, (char *) y_st) &&
981  set_belong_p(region, (char *) y_st)) {
982 
983  pips_debug(6,
984  "statement %td is not redundant "
985  "(dep. of %td).\n",
986  statement_number(st),
987  statement_number(y_st));
988 
989  return false;
990  }
991  }
992  }
993 
994  pips_debug(6,
995  "statement %td is redundant.\n",
996  statement_number(st));
997  return true;
998 }
999 
1000 
1001 /*
1002  * Simplify a redundant vertex 'v' using the following rule:
1003  */
1004 static void
1005 SimplifyRedundantVertex(vertex v, /* Successors of this vertex are updated */
1006  set /* of statement */ region,
1007  int level)
1008 {
1009  set /* of vertices */ matching_vertices = set_make(set_pointer);
1011 
1016  vertex y = successor_vertex(su);
1017  if (!common_ignore_this_vertex(region, y) &&
1020 
1021  matching_vertices = set_add_element(matching_vertices,
1022  matching_vertices,
1023  (char *) y);
1024  }
1025  }
1026 
1027  remove_dependance(v, v, OUTPUT_DEPENDANCE, 0, load_has_level(st));
1028 
1029  if (!set_empty_p(matching_vertices)) {
1030  SET_MAP(y, {
1032  0, load_has_level(st));
1033  }, matching_vertices);
1034  }
1035  }
1036 
1037  set_free(matching_vertices);
1038 }
1039 
1040 
1041 /*
1042  * Find and simplify redundant statements.
1043  */
1044 static graph
1045 DoRedundantsStatements(list /* of scc */ lsccs,
1046  graph g,
1047  set /* of statement */ region,
1048  int level,
1049  set /* of statement */ partially_invariant)
1050 {
1051  set /* of statement */ redundant = set_make(set_pointer);
1052 
1053  MAP(SCC, s, {
1054  list /* of vertex */ lv = scc_vertices(s);
1055 
1056  if (gen_length(lv) > 1) {
1057  /* Group of vertices : all are no redundant */
1058  }
1059  else {
1060  /* One statement... */
1061  vertex v = VERTEX(CAR(lv));
1063 
1064  if (set_belong_p(partially_invariant, (char *) st)) {
1065  if (vertex_redundant_p(v, g, level,
1066  region,
1067  partially_invariant,
1068  redundant)) {
1069  /* which is redundant */
1071 
1073  redundant,
1074  (char *) st);
1075  }
1076  }
1077  }
1078  }, lsccs);
1079 
1081 
1082  return g;
1083 }
1084 
1085 static graph SimplifyGraph(graph g, set region, int level, unsigned int count);
1086 static graph SupressDependances(graph g, set region, int level, unsigned int count);
1087 
1088 /*
1089  * Simplify the dependence graph.
1090  */
1091 static graph
1093  set /* of statement */ region,
1094  int level,
1095  unsigned int count)
1096 {
1097  ifdebug(5) {
1098  pips_debug(5, "start\n");
1099  pips_debug(5, "level=%d, count=%d\n", level, count);
1100 
1101  pips_debug(5, "set of statement number studied: ");
1102  SET_MAP(elt, fprintf(stderr, "%d, ", (int) statement_number((statement) elt)), region);
1103  fprintf(stderr, "\n");
1104  ifdebug(8) {
1105  pips_debug(8, "set of statement studied:\n");
1106  SET_MAP(elt, print_statement((statement) elt), region);
1107  }
1108  }
1109  list /* of scc */ lsccs;
1110 
1111  /* Find sccs */
1114  lsccs = FindAndTopSortSccs(g, region, level);
1116 
1117  FOREACH(SCC, elmt, lsccs) {
1118  /* Check if the component is strongly connected */
1119  if (strongly_connected_p(elmt, level)) {
1120  set new_region = set_make(set_pointer);
1121  new_region = vertices_to_statements(scc_vertices(elmt),
1122  new_region);
1123 
1124  g = SupressDependances(g, new_region, level, count);
1125 
1126  set_free(new_region);
1127  }
1128  }
1129 
1130  // No leak
1131  gen_free_list(lsccs);
1132 
1133  ifdebug(5) {
1134  pips_debug(5, "end\n");
1135  }
1136  return g;
1137 }
1138 
1139 
1140 /*
1141  * Supress unneeded dependances.
1142  */
1143 static graph
1145  set /* of statement */ region,
1146  int level,
1147  unsigned int count)
1148 {
1149  ifdebug(5) {
1150  pips_debug(5, "start\n");
1151  pips_debug(5, "level=%d, count=%d\n", level, count);
1152 
1153  pips_debug(5, "set of statement number studied: ");
1154  SET_MAP(elt, fprintf(stderr, "%d, ", (int) statement_number((statement) elt)), region);
1155  fprintf(stderr, "\n");
1156  ifdebug(8) {
1157  pips_debug(8, "set of statement studied:\n");
1158  SET_MAP(elt, print_statement((statement) elt), region);
1159  }
1160  }
1161  list /* of scc */ lsccs;
1162  set /* of statement */ partially_invariant = set_make(set_pointer);
1163 
1164  /* Find sccs considering only flow dependances */
1167  lsccs = FindAndTopSortSccs(g, region, level);
1169 
1170  /* Forward simplification */
1171  g = DoInvariantsStatements(lsccs, g, region, level, partially_invariant);
1172 
1173  /* Backward simplification */
1174  lsccs = gen_nreverse(lsccs);
1175  g = DoRedundantsStatements(lsccs, g, region, level, partially_invariant);
1176 
1177  // No leak
1178  gen_free_list(lsccs);
1179  set_free(partially_invariant);
1180 
1181  if (count > 1) {
1182  return SimplifyGraph(g, region, level, count-1);
1183  }
1184  else{
1186  }
1187 }
1188 
1189 
1190 /******************************************************** REMOVE DUMMY LOOPS */
1191 
1192 
1194 
1195 static list /* of entity */ depending_indices;
1196 static bool it_depends;
1197 
1198 
1199 /*
1200  * Set whether s depends from enclosing indices
1201  */
1203 {
1205  if (it_depends) gen_recurse_stop(NULL);
1206  return true;
1207 }
1208 
1209 
1211 {
1213  return true;
1214 }
1215 
1216 
1218 {
1219  list tmp = depending_indices;
1220  pips_assert("current loop index is poped",
1223  CDR(tmp) = NIL;
1224  free(tmp);
1225 }
1226 
1227 
1228 static bool drop_it(loop l)
1229 {
1231  {
1233  it_depends = false;
1237  NULL);
1238  depending_indices = NIL; /* assert? */
1239  return !it_depends;
1240  }
1241 
1242  return false;
1243 }
1244 
1245 
1246 /*
1247  * Compute the final expression of the loop index.
1248  * Follow the ANSI Fortran 77 normalization.
1249 
1250  * = m1 + MAX(INT((m2 - m1 + m3) / m3), 0) * m3
1251 
1252  */
1253 static expression
1255 {
1256  expression result;
1257  expression E0 = make_op_exp("-", m2, copy_expression(m1));
1258  expression E1 = make_op_exp("+", E0, copy_expression(m3));
1259  expression E2 = make_op_exp("/", E1, copy_expression(m3));
1260 
1261  if (expression_constant_p(E2)) {
1262  int val_E2 = expression_to_int(E2);
1263 
1264  /* max of (val_e2, 0) */
1265  if (val_E2 > 0) {
1266  expression E3 = make_op_exp("*", E2, m3);
1267  result = make_op_exp("+", E3, m1);
1268  }
1269  else {
1270  result = m1;
1271  free_expression(m3);
1272  }
1273  }
1274  else {
1275  expression zero = int_to_expression(0);
1276  expression p_int, E3, E4;
1277 
1279  E2);
1280 
1282  p_int,
1283  zero);
1284  E4 = make_op_exp("*", E3, m3);
1285  result = make_op_exp("+", m1, E4);
1286  }
1287 
1288  /* memory leak */
1289 
1290  return result;
1291 }
1292 
1293 
1294 static bool icm_loop_rwt(loop l)
1295 {
1296  statement head = stmt_head();
1297 
1298  ifdebug(5) {
1299  fprintf(stderr, "TEST : loop on %s (statement %td):\n",
1300  entity_name(loop_index(l)),
1301  statement_number(head));
1302  }
1303 
1304  if (drop_it(l))
1305  {
1306  statement index_statement;
1307  statement body = loop_body(l);
1308 
1309  expression index, m1, m2, m3;
1310 
1314 
1315  /* Assume here that index is a scalar variable... :-) */
1316  pips_assert("icm_loop_rwt", entity_scalar_p(loop_index(l)));
1317 
1318  index = make_factor_expression(1, loop_index(l));
1319 
1320  index_statement =
1321  make_assign_statement(index,
1322  compute_final_index_value(m1, m2, m3));
1323 
1326 
1327  pips_debug(5, "-> loop on %s removed (statement %td)\n",
1328  entity_name(loop_index(l)),
1329  statement_number(head));
1330 
1331  /* memory leak... */
1332  }
1333  else {
1334  pips_debug(5, "-> loop on %s NOT removed (statement %td)\n",
1335  entity_name(loop_index(l)),
1336  statement_number(head));
1337  }
1338 
1339  return true;
1340 }
1341 
1342 
1343 /*
1344  * Drop all loops l matching the pattern:
1345  * l is parallel
1346  * the body of l doesn't use indicies of the loop l.
1347  *
1348  * WARNING : the pattern is correct ????????
1349  */
1351 {
1352  /* WARNING :
1353  * We must recompute proper_effects for the program !!!
1354  * So we directly call the pass !!!!!
1355  */
1359 
1360 
1361  make_stmt_stack();
1362 
1366  NULL);
1367 
1368  free_stmt_stack();
1371 }
1372 
1373 
1374 /*********************************************************** REGENERATE CODE */
1375 
1376 
1377 /*
1378  * Simplify the dependance graph and regenerate the code.
1379  *
1380  * Using the algorithm described in Chapter xxx of Julien Zory's PhD?
1381  */
1383  graph g,
1384  set /* of statement */ region,
1385  int level,
1386  bool task_parallelize_p)
1387 {
1388  statement result = statement_undefined;
1389  graph simplified_graph = graph_undefined;
1390 
1392 
1393  debug_on("ICM_DEBUG_LEVEL");
1394  ifdebug(4) {
1395  pips_debug(9, "ICM_DEBUG_LEVEL start\n");
1396  pips_debug(4, "on statement:\n");
1397  print_statement(stat);
1398  }
1399 
1401  db_get_memory_resource(DBR_PROPER_EFFECTS,
1403  true));
1404 
1405  /* Compute has_level hash and has_indices tables */
1406 
1407  init_has_level();
1408  make_has_indices_map();
1409 
1410  indices = NIL;
1411 
1412  gen_multi_recurse(stat,
1414  statement_domain, statement_mark, gen_null, /* STATEMENT */
1415  NULL);
1416 
1418 
1419  /* Simplify the dependance graph */
1420 
1421  simplified_graph = copy_graph(g);
1422 
1423  /* Definir le mapping entre les vertex originaux et les vertex copies */
1424 
1425  ifdebug(4) {
1426  pips_debug(4, "Original graph:\n");
1429  simplified_graph);
1430  }
1431 
1433 
1434  simplified_graph = SimplifyGraph(simplified_graph,
1435  region,
1436  level,
1438 
1440 
1441  ifdebug(4) {
1442  pips_debug(4, "Simplified graph:\n");
1445  simplified_graph);
1446  }
1447 
1448  close_has_level();
1449  free_has_indices_map();
1451  /* CodeGenerate reload the
1452  * proper_rw_effects table, so we must
1453  * reset before... */
1454 
1455  pips_debug(9, "ICM_DEBUG_LEVEL stop\n");
1456  debug_off();
1457 
1458  /* Generate the code (CodeGenerate don't use the first
1459  * parameter...) */
1460  result = CodeGenerate(/* big hack */ statement_undefined,
1461  simplified_graph,
1462  region,
1463  level,
1464  task_parallelize_p);
1465  free_graph(simplified_graph);
1466 
1467  ifdebug(4) {
1468  pips_debug(4, "Intermediate code:\n");
1469  print_statement(result);
1470  }
1471 
1472  /* Remove dummy loops. */
1473  drop_dummy_loops(result);
1474 
1475  ifdebug(4) {
1476  pips_debug(4, "Final code:\n");
1477  print_statement(result);
1478  }
1479 
1480  return result;
1481 }
1482 
1483 
1484 /*************************************************************** ENTRY POINT */
1485 
1486 
1487 /* Phase that hoists loop invariant code out of loops.
1488 
1489  @param[in] module_name
1490 
1491  @return true because everything should go fine
1492 
1493  Prepare some stuffs and call icm_codegen...
1494 */
1496 {
1500 
1501  set_bool_property( "GENERATE_NESTED_PARALLEL_LOOPS", true );
1502  set_bool_property( "RICE_DATAFLOW_DEPENDENCE_ONLY", false );
1503 
1505  db_get_memory_resource(DBR_CODE,
1506  module_name,
1507  true));
1508 
1510 
1512 
1513  debug_on("ICM_DEBUG_LEVEL");
1514 
1515  ifdebug(7)
1516  {
1517  fprintf(stderr,
1518  "\nTesting NewGen consistency for initial code %s:\n",
1519  module_name);
1521  fprintf(stderr," NewGen consistent statement\n");
1522  }
1523 
1524  ifdebug(1) {
1525  pips_debug(1, "original sequential code:\n\n");
1527  }
1528 
1529  if (graph_undefined_p(dg)) {
1530  dg = (graph) db_get_memory_resource(DBR_DG, module_name, true);
1531  }
1532  else {
1533  pips_internal_error("dg should be undefined");
1534  }
1535 
1536  enclosing = 0;
1538 
1539  ifdebug(7) {
1540  fprintf(stderr, "\ntransformed code %s:",module_name);
1542  fprintf(stderr," gen consistent ");
1543  }
1544 
1545  // Uselessly reinitialize ordering_to_statement, even if it not set...
1548 
1550 
1551  dg = graph_undefined;
1555 
1556  debug_off();
1557  return true;
1558 }
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
static void stmt_rewrite(statement s)
Definition: graph.c:232
void free_graph(graph p)
Definition: graph.c:23
graph copy_graph(graph p)
GRAPH.
Definition: graph.c:20
expression copy_expression(expression p)
EXPRESSION.
Definition: ri.c:850
bool statement_consistent_p(statement p)
Definition: ri.c:2195
void free_expression(expression p)
Definition: ri.c:853
static int count
Definition: SDG.c:519
static reference ref
Current stmt (an integer)
Definition: adg_read_paf.c:163
static bool stmt_filter(statement s)
modifies global var current_caller_stmt
Definition: alias_pairs.c:222
@ INT
Definition: atomic.c:48
static graph dg
dg is the dependency graph ; FIXME : should not be static global ?
Definition: chains.c:124
bool clean_up_sequences(statement s)
Recursively clean up the statement sequences by fusing them if possible and by removing useless one.
static list successors(list l)
#define SCC(x)
SCC.
Definition: dg.h:315
#define conflict_sink(x)
Definition: dg.h:167
#define cone_levels(x)
Definition: dg.h:128
#define CONFLICT(x)
CONFLICT.
Definition: dg.h:134
#define dg_arc_label_conflicts(x)
Definition: dg.h:201
#define scc_vertices(x)
Definition: dg.h:345
#define conflict_source(x)
Definition: dg.h:165
#define cone_undefined
Definition: dg.h:104
#define conflict_cone(x)
Definition: dg.h:169
#define region
simulation of the type region
void proper_effects_of_module_statement(statement)
list load_proper_rw_effects_list(statement)
void reset_proper_rw_effects(void)
void init_proper_rw_effects(void)
void set_proper_rw_effects(statement_effects)
void generic_effects_reset_all_methods(void)
void set_methods_for_proper_simple_effects(void)
list words_effect(effect)
#define effect_any_reference(e)
FI: cannot be used as a left hand side.
#define effect_write_p(eff)
#define effect_action(x)
Definition: effects.h:642
#define action_write_p(x)
Definition: effects.h:314
#define action_read_p(x)
Definition: effects.h:311
#define STATEMENT_EFFECTS_MAP(k, v, c, f)
Definition: effects.h:1057
#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
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
void free(void *)
#define successor_vertex(x)
Definition: graph.h:118
#define successor_arc_label(x)
Definition: graph.h:116
struct _newgen_struct_graph_ * graph
Definition: graph.h:31
#define vertex_successors(x)
Definition: graph.h:154
#define graph_undefined_p(x)
Definition: graph.h:61
#define SUCCESSOR(x)
SUCCESSOR.
Definition: graph.h:86
#define graph_vertices(x)
Definition: graph.h:82
#define graph_undefined
Definition: graph.h:60
#define VERTEX(x)
VERTEX.
Definition: graph.h:122
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
const char * get_current_module_name(void)
Get the name of the current module.
Definition: static.c:121
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
void gen_recurse_stop(void *obj)
Tells the recursion not to go in this object.
Definition: genClib.c:3251
void gen_multi_recurse(void *o,...)
Multi recursion visitor function.
Definition: genClib.c:3428
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
instruction make_instruction_block(list statements)
Build an instruction block from a list of statements.
Definition: instruction.c:106
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
size_t gen_length(const list l)
Definition: list.c:150
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#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 MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
string db_get_memory_resource(const char *rname, const char *oname, bool pure)
Return the pointer to the resource, whatever it is.
Definition: database.c:755
#define DB_PUT_MEMORY_RESOURCE(res_name, own_name, res_val)
conform to old interface.
Definition: pipsdbm-local.h:66
statement make_assign_statement(expression, expression)
Definition: statement.c:583
statement update_statement_instruction(statement, instruction)
Replace the instruction in statement s by instruction i.
Definition: statement.c:3039
bool declaration_statement_p(statement)
Had to be optimized according to Beatrice Creusillet.
Definition: statement.c:224
bool expression_constant_p(expression)
HPFC module by Fabien COELHO.
Definition: expression.c:2453
static expression compute_final_index_value(expression m1, expression m2, expression m3)
Definition: icm.c:1254
static bool loop_level_in(loop l)
Definition: icm.c:227
static bool common_ignore_this_vertex(set region, vertex v)
Definition: icm.c:536
bool invariant_code_motion(const char *module_name)
Phase that hoists loop invariant code out of loops.
Definition: icm.c:1495
#define ALL_DEPENDANCES
Definition: icm.c:56
static bool it_depends
Definition: icm.c:1196
static bool inv_entity_filter(entity e)
Definition: icm.c:635
#define INPUT_DEPENDANCE
Definition: icm.c:55
statement vertex_to_statement(vertex v)
Vertex_to_statement looks for the statement that is pointed to by vertex v.
Definition: util.c:45
static list depending_indices
of entity
Definition: icm.c:1195
static bool does_it_depend(statement s)
Set whether s depends from enclosing indices.
Definition: icm.c:1202
static graph DoRedundantsStatements(list lsccs, graph g, set region, int level, set partially_invariant)
Definition: icm.c:1045
static bool invariant_ignore_this_successor(vertex v, set region, successor su, int level)
Definition: icm.c:570
static void drop_dummy_loops(statement s)
Definition: icm.c:1350
static bool push_depending_index(loop l)
Definition: icm.c:1210
static bool statement_depend_of_indices_p(statement st, list indices, int level)
Definition: icm.c:596
static bool vertex_invariant_p(vertex v, graph g, int level, set region, set invariant)
Definition: icm.c:736
static bool action_dependance_p(conflict c, int dependance_type)
Definition: icm.c:258
static list remove_dependances_from_successors(list successors, vertex v2, int dependance_type, int level_min, int level_max)
of successor
Definition: icm.c:428
#define NB_SIMPLIFY_PASSES
Set to 2 if we want to simplify in two passes.
Definition: icm.c:49
static bool icm_loop_rwt(loop l)
Definition: icm.c:1294
static set vertices_to_statements(list vl, set ss)
of statement
Definition: icm.c:166
static bool exist_non_self_dependance_from_vertex_p(vertex v, int dependance_type, int level)
Definition: icm.c:327
static bool expression_invariant
Definition: icm.c:63
static void remove_dependance(vertex v1, vertex v2, int dependance_type, int level_min, int level_max)
Definition: icm.c:488
#define FLOW_DEPENDANCE
Definition: icm.c:52
static void prettyprint_vertex(FILE *fd, vertex v)
Definition: icm.c:136
static statement icm_codegen(statement stat, graph g, set region, int level, bool task_parallelize_p)
Definition: icm.c:1382
static int reference_level
Definition: icm.c:61
static graph SupressDependances(graph g, set region, int level, unsigned int count)
Definition: icm.c:1144
void dump_sef(statement_effects se)
icm.c
Definition: icm.c:75
static void prettyprint_conflict(FILE *fd, conflict c)
Definition: icm.c:99
static set invariant_vertex_to_invariant_entities(vertex v, set rs)
of entity
Definition: icm.c:178
static graph DoInvariantsStatements(list lsccs, graph g, set region, int level, set partially_invariant)
Definition: icm.c:848
#define OUTPUT_DEPENDANCE
Definition: icm.c:54
static list indices
Definition: icm.c:204
static bool vertex_redundant_p(vertex v, __attribute__((unused)) graph g, int level, set region, set partially_invariant, set redundant)
Definition: icm.c:935
static void pop_depending_index(loop l)
Definition: icm.c:1217
static bool drop_it(loop l)
Definition: icm.c:1228
static set invariant_entities
of entity
Definition: icm.c:64
static void SimplifyInvariantVertex(vertex v, set region, int level)
Definition: icm.c:806
static bool expressions_invariant_p(list le)
Definition: icm.c:648
static graph SimplifyGraph(graph g, set region, int level, unsigned int count)
Definition: icm.c:1092
static list remove_dependance_from_conflicts(list conflicts, int dependance_type, int level_min, int level_max)
of conflict
Definition: icm.c:369
static list remove_dependance_from_levels(list levels, int level_min, int level_max)
of level
Definition: icm.c:346
static bool statement_mark(statement s)
Definition: icm.c:213
static void loop_level_out(__attribute__((unused)) loop l)
Definition: icm.c:242
static bool ref_flt(reference r)
Definition: icm.c:642
static int depth
Definition: icm.c:205
#define ANTI_DEPENDANCE
Definition: icm.c:53
void print_list_entities(list l)
Definition: icm.c:151
static bool vertex_partially_invariant_p(vertex v, __attribute__((unused)) graph g, __attribute__((unused)) int level, __attribute__((unused)) set invariant)
Definition: icm.c:668
static void prettyprint_successor(FILE *fd, successor su)
Definition: icm.c:119
static void SimplifyRedundantVertex(vertex v, set region, int level)
Definition: icm.c:1005
static bool icm_ignore_this_successor(vertex v, set region, successor su, int level)
Definition: icm.c:547
static bool dependance_vertices_p(vertex v1, vertex v2, int dependance_type, int level)
Test the existence of a given dependence between two vertices v1, v2.
Definition: icm.c:282
static statement mod_stat
We want to keep track of the current statement inside the recurse.
Definition: impact_check.c:41
static int redundant(Pproblem XX, int i1, int i2)
Definition: isolve.c:720
#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_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_internal_error
Definition: misc-local.h:149
#define debug_off()
Definition: misc-local.h:160
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
#define GENERIC_LOCAL_MAPPING(name, result, type)
to allow mappings local to a file.
#define DEFINE_LOCAL_STACK(name, type)
bool set_empty_p(const set)
tell whether set s is empty.
Definition: set.c:367
#define set_undefined
Definition: newgen_set.h:48
#define SET_MAP(element, code, the_set)
Definition: newgen_set.h:54
void set_free(set)
Definition: set.c:332
bool set_belong_p(const set, const void *)
Definition: set.c:194
@ set_pointer
Definition: newgen_set.h:44
set set_make(set_type)
Create an empty set of any type but hash_private.
Definition: set.c:102
set set_add_element(set, const set, const void *)
Definition: set.c:152
hash_table set_ordering_to_statement(statement s)
To be used instead of initialize_ordering_to_statement() to make sure that the hash table ots is in s...
Definition: ordering.c:172
void reset_ordering_to_statement(void)
Reset the mapping from ordering to statement.
Definition: ordering.c:185
static char * module
Definition: pips.c:74
void print_statement(statement)
Print a statement on stderr.
Definition: statement.c:98
void set_bool_property(const char *, bool)
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
#define MAX_OPERATOR_NAME
#define INT_GENERIC_CONVERSION_NAME
generic conversion names.
#define make_statement_list(stats...)
easy list constructor
entity local_name_to_top_level_entity(const char *n)
This function try to find a top-level entity from a local name.
Definition: entity.c:1450
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
int expression_to_int(expression exp)
================================================================
Definition: expression.c:2205
expression make_factor_expression(int coeff, entity vari)
Some functions to generate expressions from vectors and constraint systems.
Definition: expression.c:1631
expression MakeBinaryCall(entity f, expression eg, expression ed)
Creates a call expression to a function with 2 arguments.
Definition: expression.c:354
expression int_to_expression(_int i)
transform an int into an expression and generate the corresponding entity if necessary; it is not cle...
Definition: expression.c:1188
expression make_op_exp(char *op_name, expression exp1, expression exp2)
================================================================
Definition: expression.c:2012
expression MakeUnaryCall(entity f, expression a)
Creates a call expression to a function with one argument.
Definition: expression.c:342
bool entity_scalar_p(entity)
The concrete type of e is a scalar type.
Definition: variable.c:1113
int variable_entity_dimension(entity)
variable_entity_dimension(entity v): returns the dimension of variable v; scalar have dimension 0.
Definition: variable.c:1293
#define loop_body(x)
Definition: ri.h:1644
#define loop_execution(x)
Definition: ri.h:1648
#define reference_variable(x)
Definition: ri.h:2326
#define loop_domain
newgen_language_domain_defined
Definition: ri.h:218
#define range_upper(x)
Definition: ri.h:2290
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define range_increment(x)
Definition: ri.h:2292
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define instruction_undefined
Definition: ri.h:1454
#define reference_domain
newgen_range_domain_defined
Definition: ri.h:338
#define entity_name(x)
Definition: ri.h:2790
#define reference_indices(x)
Definition: ri.h:2328
#define range_lower(x)
Definition: ri.h:2288
#define statement_instruction(x)
Definition: ri.h:2458
#define loop_range(x)
Definition: ri.h:1642
#define statement_number(x)
Definition: ri.h:2452
#define execution_parallel_p(x)
Definition: ri.h:1211
#define loop_index(x)
Definition: ri.h:1640
#define statement_undefined
Definition: ri.h:2419
bool strongly_connected_p(scc s, int l)
this function returns true if scc s is stronly connected at level l, i.e.
Definition: codegen.c:284
statement CodeGenerate(statement __attribute__((unused)) stat, graph g, set region, int l, bool task_parallelize_p)
This function implements Allen & Kennedy's algorithm.
Definition: codegen.c:393
int enclosing
This is an horrendous hack.
Definition: rice.c:67
statement rice_statement(statement stat, int l, statement(*codegen_fun)(statement, graph, set, int, bool))
Definition: rice.c:82
void set_sccs_drivers(bool(*)(set, vertex), bool(*)(vertex, set, successor, int))
scc.c
void reset_sccs_drivers(void)
Definition: scc.c:98
list FindAndTopSortSccs(graph, set, int)
Definition: scc.c:317
void prettyprint_dependence_graph(FILE *, statement, graph)
Print all edges and arcs.
Definition: util.c:177
#define level
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
#define ifdebug(n)
Definition: sg.c:47
GENERIC_LOCAL_FUNCTION(directives, step_directives)
Copyright 2007, 2008, 2009 Alain Muller, Frederique Silber-Chaussumier.
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
Definition: statement.c:54
void print_words(FILE *fd, cons *lw)
Definition: print.c:263
#define exp
Avoid some warnings from "gcc -Wshadow".
Definition: vasnprintf.c:207