PIPS
loop.c
Go to the documentation of this file.
1 /*
2 
3  $Id: loop.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 
25 /* Some generic methods about loops and list of loops.
26 
27  There are many things elsewhere that should be factored out into here
28  (static controlize...).
29 
30 */
31 
32 #ifdef HAVE_CONFIG_H
33  #include "pips_config.h"
34 #endif
35 #include <stdio.h>
36 
37 #include "linear.h"
38 #include "genC.h"
39 
40 #include "misc.h"
41 #include "properties.h"
42 
43 #include "ri.h"
44 #include "ri-util.h"
45 
46 
47 
48 /* @defgroup loop Methods dealing with loops
49 
50  @{
51 */
52 
53 // stupid counter used by one debug message in ricedg
54 int Nbrdo;
55 
56 DEFINE_CURRENT_MAPPING(enclosing_loops, list)
57 
59 {
60  /* warning: there are shared lists...
61  */
63 
65  {
66  if (l && !hash_defined_p(seen, l))
67  {
68  gen_free_list((list)l);
69  hash_put(seen, l, (char*) 1);
70  }
71  },
73 
76 }
77 
79 
82  list loops,
83  unstructured u)
84 {
85  list blocs = NIL ;
86 
88  unstructured_control(u), blocs) ;
89 
90  gen_free_list(blocs) ;
91 }
92 
93 static void
95  list loops,
96  statement s)
97 {
99 
101 
102  switch(instruction_tag(i)) {
103 
106  instruction_block(i));
107  break;
108 
109  case is_instruction_loop:
110  {
112  Nbrdo++;
114  gen_free_list(nl);
115  break;
116  }
117 
118  case is_instruction_test:
121  break;
122 
125  break;
126 
127  case is_instruction_call:
128  break;
130  break;
131  case is_instruction_goto:
132  pips_internal_error("Go to instruction in CODE internal representation");
133  break;
134 
137  break ;
138  }
139 
140  case is_instruction_forloop: {
141  /*
142  pips_user_error("Use property FOR_TO_WHILE_LOOP_IN_CONTROLIZER or "
143  "FOR_TO_DO_LOOP_IN_CONTROLIZER to convert for loops into while loops\n");
144  */
146  break ;
147  }
148  default:
149  pips_internal_error("unexpected tag %d", instruction_tag(i));
150  }
151 }
152 
153 
156 {
157  statement_mapping loops_map;
158  loops_map = MAKE_STATEMENT_MAPPING();
159  Nbrdo = 0;
160  rloops_mapping_of_statement(loops_map, NIL, stat);
161 
162  if (get_debug_level() >= 7) {
164  fprintf(stderr, "statement %td in loops ",
165  statement_number((statement) stat));
166  FOREACH (STATEMENT, s,loops)
167  fprintf(stderr, "%td ", statement_number(s));
168  fprintf(stderr, "\n");
169  }, loops_map)
170  }
171  return(loops_map);
172 }
173 
174 
175 static bool
177 {
179 
180  switch(instruction_tag(i))
181  {
183  MAPL(ps, {
185  region)) {
186  return(false);
187  }
188  }, instruction_block(i));
189  return(true);
190 
191  case is_instruction_loop:
192  region = set_add_element(region, region, (char *) stat);
194  region));
195 
196  case is_instruction_call:
197  region = set_add_element(region, region, (char *) stat);
198  return(true);
199 
201  case is_instruction_goto:
203  case is_instruction_test:
205  return(false);
206  default:
207  pips_internal_error("unexpected tag %d", instruction_tag(i));
208  }
209 
210  return((bool) 0); /* just to avoid a gcc warning */
211 }
212 
213 
214 /* this functions checks if Kennedy's algorithm can be applied on the
215 loop passed as argument. If yes, it returns a set containing all
216 statements belonging to this loop including the initial loop itself.
217 otherwise, it returns an undefined set.
218 
219 Our version of Kennedy's algorithm can only be applied on loops
220 containing no test, goto or unstructured control structures. */
222 statement l;
223 {
224  set r;
225 
226  pips_assert("distributable_loop", statement_loop_p(l));
227 
228  r = set_make(set_pointer);
229 
230  if (distributable_statement_p(l, r)) {
231  return(r);
232  }
233 
234  set_free(r);
235  return(set_undefined);
236 }
237 
238 
239 /* returns true if loop lo's index is private for this loop */
241 loop lo;
242 {
243  if( lo == loop_undefined ) {
244  pips_internal_error("Loop undefined");
245  }
246 
247  return((entity) gen_find_eq(loop_index(lo), loop_locals(lo)) !=
249 }
250 
251 
252 /* this function returns the set of all statements belonging to the given loop
253  even if the loop contains test, goto or unstructured control structures */
255 statement l;
256 {
257  set r;
258 
259  pips_assert("distributable_loop", statement_loop_p(l));
260 
261  r = set_make(set_pointer);
262  region_of_statement(l,r);
263  return(r);
264 }
265 
266 
267 /* Should be rewritten with a gen_recurse to deal with the recent RI...
268  */
270 statement stat;
271 set region;
272 {
274 
275  switch(instruction_tag(i)) {
276 
278  MAPL(ps, {
280  }, instruction_block(i));
281  break;
282 
283  case is_instruction_loop:{
284  region = set_add_element(region, region, (char *) stat);
286  break;
287  }
288 
289  case is_instruction_call:
291  region = set_add_element(region, region, (char *) stat);
292  break;
293 
294  case is_instruction_goto:
295  region = set_add_element(region, region, (char *) stat);
296  break;
297 
298  case is_instruction_test:
299  /* The next statement is added by Y.Q. 12/9.*/
300  region = set_add_element(region, region, (char *) stat);
303  break;
304 
307  cons *blocs = NIL;
308 
309  CONTROL_MAP(c, {
311  }, unstructured_control(u), blocs) ;
312 
313  gen_free_list(blocs) ;
314  break;
315  }
316 
317  default:
318  pips_internal_error("unexpected tag %d", instruction_tag(i));
319  }
320 }
321 
322 
323 /** Get the variables local or private to a loop
324 
325  The function can also remove from that list all the variables that are
326  localy declared in the loop statement body and the loop index using
327  the apropriate flags.
328 
329  @param obj, the loop to look at.
330 
331  @param local, set to true to remove the the variables that are localy
332  declared.
333 
334  @param index, set to true to remove the loop index variable
335 
336  @return a list of entities that are private in the current * context.
337 */
338 list loop_private_variables_as_entites (loop obj, bool local, bool index) {
339  // List of entities that are private to the loop according to the previous
340  // phases. For historical reasons private variables are stored in the
341  // locals field of the loop.
342  list result = gen_copy_seq (loop_locals(obj));
343 
344  ifdebug(9) {
345  pips_debug (9, "private entites to the loop:\n");
346  print_entities (result);
347  fprintf (stderr, "\n");
348  }
349 
350  if (local ) {
351  // List of localy declared entities that are stored in loop body
352  list decl_var = statement_declarations (loop_body (obj));
353  ifdebug(9) {
354  pips_debug (9, "localy declaed entites:\n");
355  print_entities (decl_var);
356  fprintf (stderr, "\n");
357  }
358  gen_list_and_not (&result, decl_var);
359  }
360 
361  if (index ) {
362  pips_debug (9, "loop_indexl to remove : %s\n", entity_name (loop_index(obj)));
363  gen_remove (&result, loop_index(obj));
364  }
365 
366  sort_list_of_entities(result);
367 
368  return result;
369 }
370 
371 
372 
373 /************************************** SORT ALL LOCALS AFTER PRIVATIZATION */
374 
375 static void loop_sort_locals(loop l)
376 {
377  list /* of entity */ le = loop_locals(l);
378  if (le) sort_list_of_entities(le);
379 }
380 
382 {
384 }
385 
386 
387 /* Test if a loop is parallel
388 
389  @param l is the loop to test
390 
391  @return true if the loop has a parallel execution mode
392 */
395 }
396 
397 
398 /* Test if a loop is sequential
399 
400  @param l is the loop to test
401 
402  @return true if the loop has a sequential execution mode
403 */
406 }
407 
408 
409 /* Test if a statement is a parallel loop.
410 
411  It tests the parallel status of the loop but should test extensions
412  such as OpenMP pragma and so on. TODO...
413 
414  @param s is the statement that may own the loop. We need this statement
415  to get the pragma for the loop.
416  instruction with a loop in it.
417 
418  @return true only if the statement is a parallel loop.
419 */
421  if (statement_loop_p(s)) {
423  loop l = instruction_loop(i);
424 
425  return loop_parallel_p(l);
426  }
427  return false;
428 }
429 
430 
431 /** Compute the depth of a parallel perfect loop-nest
432 
433  @return the depth of parallel perfect loop-nest found. If there is no
434  loop here, return 0
435  */
437  // We can have blocks and declarations surrounding loops
438  while(statement_block_p(s)) {
439  statement prev = s;
440  for(list iter=statement_block(s);!ENDP(iter);POP(iter)) {
441  statement st = STATEMENT(CAR(iter));
442  // We can ignore declarations... until there is an initialization !
443  if(declaration_statement_p(st)) {
447  return 0;
448  }
449  }
450  continue;
451  } else if(gen_length(iter)!=1) {
452  return 0;
453  } else {
454  s = st;
455  }
456  }
457  if(s == prev) return 0;
458  }
459 
461  // Get the loop
462  loop l = statement_loop(s);
463  // Count the current one and dig into the statement of the loop:
465  } else {
466  /* No parallel loop found here */
467  return 0;
468  }
469 }
470 
471 /** Compute the depth of a perfect loop-nest
472 
473  @return the depth of perfect loop-nest found. If there is no
474  loop here, return 0
475  */
477  // We can have blocks and declarations surrounding loops
478  if(statement_block_p(s)) {
479  if(ENDP(statement_block(s))) return 0;
480  for(list iter=statement_block(s);!ENDP(iter);POP(iter)) {
481  statement st = STATEMENT(CAR(iter));
482  if(declaration_statement_p(st))//ok, skip this
483  continue;
484  else if(gen_length(iter)!=1) return 0;
485  else
486  s = st;
487  }
488  }
489 
490  if(statement_loop_p(s)) {
491  // Get the loop
492  loop l = statement_loop(s);
493  // Count the current one and dig into the statement of the loop:
494  return 1 + depth_of_perfect_loop_nest(loop_body(l));
495  } else {
496  /* No loop found here */
497  return 0;
498  }
499 }
500 
501 
502 /** Return the inner loop in a perfect loop-nest
503 
504  @param stat is the statement to test
505 
506  @return the loop statement if we have a perfect loop nest, else statement_undefined
507 */
510  tag t = instruction_tag(ins);
511 
512  switch(t) {
513  case is_instruction_block: {
514  list lb = instruction_block(ins);
515 
516  if(lb != NIL && (lb->cdr) != NIL && (lb->cdr)->cdr == NIL
517  && (continue_statement_p(STATEMENT(CAR(lb))))) {
519  } else if(lb != NIL && (lb->cdr) == NIL) {
521  }
522  break;
523  }
524  case is_instruction_loop: {
525  return stat;
526  }
527  default:
528  break;
529  }
530 
531  return statement_undefined;
532 
533 }
534 
535 
536 /** Test if a statement is a perfect loop-nest
537 
538  @param stat is the statement to test
539 
540  @return true if the statement is a perfect loop-nest
541 */
542 bool
545  tag t = instruction_tag(ins);
546 
547  switch( t ) {
548  case is_instruction_block: {
549  list lb = instruction_block(ins);
550 
551  if ( lb != NIL && (lb->cdr) != NIL && (lb->cdr)->cdr == NIL
552  && ( continue_statement_p(STATEMENT(CAR(lb->cdr))) ) ) {
554  return true;
555  else
556  return(perfectly_nested_loop_p(STATEMENT(CAR(lb))));
557  }
558  else if ( lb != NIL && (lb->cdr) == NIL )
559  return(perfectly_nested_loop_p(STATEMENT(CAR(lb))));
560  else if ( lb != NIL ) {
561  /* biased for WP65 */
562  return assignment_block_p(ins);
563  }
564  else
565  /* extreme case: empty loop nest */
566  return true;
567  break;
568  }
569  case is_instruction_loop: {
570  loop lo = instruction_loop(ins);
571  statement sbody = loop_body(lo);
572 
573  if ( assignment_statement_p(sbody) )
574  return true;
575  else
576  return(perfectly_nested_loop_p(sbody));
577  break;
578  }
579  default:
580  break;
581  }
582 
583  return false;
584 }
585 
586 
587 /* Extract the body of a perfectly nested loop body.
588  */
589 statement
591  instruction ins = statement_instruction(loop_nest);
592 
593  switch(instruction_tag(ins)) {
594 
595  case is_instruction_call:
597  case is_instruction_test:
598  /* By hypothesis we are in a perfectly nested loop and since it is
599  not a loop, we've reached the loop body: */
600  return loop_nest;
601 
602  case is_instruction_block: {
603  list lb = instruction_block(ins);
604  if (lb == NIL)
605  /* The loop body is an empty block, such as { } in C: */
606  return loop_nest;
607  statement first_s = STATEMENT(CAR(lb));
608  instruction first_i = statement_instruction(first_s);
609 
610  if(instruction_call_p(first_i))
611  return loop_nest;
612  else {
613  if(instruction_block_p(first_i))
615  else {
616  pips_assert("perfectly_nested_loop_to_body",
617  instruction_loop_p(first_i));
618  return perfectly_nested_loop_to_body( first_s);
619  }
620  }
621  break;
622  }
623  case is_instruction_loop: {
624  /* It is another loop: dig into it to reach the loop body: */
625  statement sbody = loop_body(instruction_loop(ins));
626  return (perfectly_nested_loop_to_body(sbody));
627  break;
628  }
629  default:
630  pips_internal_error("illegal tag");
631  break;
632  }
633  return(statement_undefined); /* just to avoid a warning */
634 }
635 
636 
637 /** Extract the loop-body of a perfect loop-nest at a given depth
638 
639  @param s is the loop-nest statement to dig into
640 
641  @param depth is the diving depth
642 
643  @return the loop-body found at the given depth
644  */
645 statement
647  // To have it working for depth = 0 too:
648  statement body = s;
649  /* ifdebug(2) { */
650  /* pips_debug(1, "Look at statement at depth 0:\n"); */
651  /* print_statement(body); */
652  /* } */
653  for(int i = 0; i < depth; i++) {
654 
655  // We can have blocks and declarations surrounding loops
656  while(statement_block_p(body)) {
657  for(list iter=statement_block(body);!ENDP(iter);POP(iter)) {
658  statement st = STATEMENT(CAR(iter));
659  if(declaration_statement_p(st))//ok, skip this
660  continue;
661  else if(gen_length(iter)!=1) pips_internal_error("should be a perfectly nested loop\n");
662  else
663  body = st;
664  }
665  }
666 
667  pips_assert("The statement is a loop", statement_loop_p(body));
668  // Dive into one loop:
669  body = loop_body(statement_loop(body));
670 
671  /* ifdebug(2) { */
672  /* pips_debug(1, "Look at statement at depth %d:\n", i + 1); */
673  /* print_statement(body); */
674  /* } */
675  }
676  // We can have blocks and declarations surrounding loops
677  while(statement_block_p(body)&&gen_length(statement_block(body))==1) {
678  body=STATEMENT(CAR(statement_block(body)));
679  }
680 
681  return body;
682 }
683 
684 
685 /** Get the index of the loop at a given depth inside a loop-nest
686 
687  @param s is the loop-nest statement to dig into
688 
689  @param depth is the diving depth
690 
691  @return the loop-body found at the given depth
692  */
693 entity
696  /* there may be some declarations before */
697  while(statement_block_p(preloop)) {
698  for(list iter= statement_block(preloop);!ENDP(iter);POP(iter))
699  if(declaration_statement_p(STATEMENT(CAR(iter)))) continue;
700  else { preloop = STATEMENT(CAR(iter)) ; break ;}
701  }
702 
703  return loop_index(statement_loop(preloop));
704 }
705 
706 
707 /*
708  returns the numerical value of loop l increment expression.
709  aborts if this expression is not an integral constant expression.
710  modification : returns the zero value when it isn't constant
711  Y.Q. 19/05/92
712 */
713 int
715  range r = loop_range(l);
716  expression ic = range_increment(r);
717  normalized ni;
718  int inc;
719 
720  ni = NORMALIZE_EXPRESSION(ic);
721 
722  if (! EvalNormalized(ni, &inc)){
723  /*user_error("loop_increment_value", "increment is not constant");*/
724  debug(8,"loop_increment_value", "increment is not constant");
725  return(0);
726  }
727  return(inc);
728 }
729 
730 
731 /** Test if a loop has a constant step loop
732  */
734  pips_debug(7, "doing\n");
736 }
737 
738 
739 /** Test if a loop does have a 1-increment step
740  */
742  expression ri;
743  entity ent;
744 
745  pips_debug(7, "doing\n");
746 
747  if (!constant_step_loop_p(l))
748  // No way for a non-constant step to be a 1-constant :-)
749  return(false);
750 
751  ri = range_increment(loop_range(l));
753  return strcmp(entity_local_name(ent), "1") == 0;
754 }
755 
756 
757 /*************************************************************** COUNT LOOPS */
758 
759 /** To store the number of sequential and parallel loops */
760 static int nseq, npar;
761 
762 
764 {
765  if (loop_parallel_p(l))
766  npar++;
767  else
768  nseq++;
769 }
770 
771 
772 /**
773  Compute the number of parallel and sequential loops found in a
774  statement and update given variables
775 
776  @param stat is the statement to dig into
777 
778  @param pseq point to the variable to update with the number of
779  sequential loops found
780 
781  @param ppr point to the variable to update with the number of parallel
782  loops found
783  */
785  int * pseq,
786  int * ppar) {
787  nseq=0, npar=0;
789  *pseq=nseq, *ppar=npar;
790 }
791 
792 
793 /**
794  Compute the number of parallel and sequential loops found in a
795  statement and output them on a stream with a message before
796 
797  @param out is the stream to send the information to
798 
799  @param msg is the message to prepend
800 
801  @param s is the statement to dig into
802  */
804  string msg,
805  statement s) {
806  int seq, par;
808  fprintf(out, "%s: %d seq loops, %d par loops\n", msg, seq, par);
809 }
810 
811 
812 /* Print out the number of sequential versus parallel loops.
813  */
815  const char* module, /**< the module name */
816  const char* msg, /**< an additional message */
817  statement s /**< the module statement to consider */) {
818  if (get_bool_property("PARALLELIZATION_STATISTICS"))
819  {
820  fprintf(stderr, "%s %s parallelization statistics", module, msg);
821  print_number_of_loop_statistics(stderr, "", s);
822  }
823 }
824 
825 /* Duplicate a loop list. */
827 {
828  list nll = gen_full_copy_list(ll);
829 
830  return nll;
831 }
832 
833 /* This is an ad'hoc function designed for
834  do_loop_unroll_with_epilogue(). The expression and execution
835  parameters are reused directly in the new loop, but the body must
836  be cloned. Compared to make_loop(), this function adds the cloning
837  and the wrapping into an instruction and a statement.
838 */
840  expression low,
841  expression up,
842  expression inc,
843  statement b,
844  execution e)
845 {
846  /* Loop range is created */
847  range rg = make_range(low, up, inc);
848 
849  ifdebug(9) {
850  pips_assert("new range is consistent", range_consistent_p(rg));
851  }
852 
853  /* Create body of the loop, with updated index */
857  NIL,
859  statement body = clone_statement(b, cc);
860  free_clone_context(cc);
861 
862  ifdebug(9) {
863  pips_assert("cloned body is consistent", statement_consistent_p(body));
864  /* "gen_copy_tree returns bad statement\n"); */
865  }
866 
867  entity label_entity = entity_empty_label();
868 
869  ifdebug(9) {
870  pips_assert("the cloned is consistent",
871  statement_consistent_p(body));
872  }
873 
875  make_loop(i,
876  rg,
877  body,
878  label_entity,
879  e,
880  NIL));
881 
882  ifdebug(9) {
883  pips_assert("inst is consistent",
885  }
886 
888  return stmt;
889 }
890 
891 /* If statement s is a perfectly loop nest, return the corresponding
892  loop list. If not, the list returned is empty. */
894 {
895  list l = NIL;
896  statement cs = s;
897 
898  while(statement_loop_p(cs)) {
899  l = gen_nconc(l, CONS(STATEMENT,cs, NIL));
900  cs = loop_body(statement_loop(cs));
901  if(statement_block_p(cs)) {
902  list sl = statement_block(cs);
903  if(gen_length(sl)==1)
904  cs = STATEMENT(CAR(sl));
905  }
906  }
907 
908  return l;
909 }
910 
912 {
913  bool return_val = false;
914  expression low = range_lower(r); int i_low;
915  expression up = range_upper(r); int i_up;
916  expression inc = range_increment(r); int i_inc;
920  if (i_inc > 0 && i_up >= i_low) {
921  // Increasing case
922  return_val = true;
923  }
924  else if (i_inc < 0 && i_up <= i_low) {
925  // Decreasing case
926  return_val = true;
927  }
928  }
929  return return_val;
930 }
931 
932 /**
933  * \brief Check if loop bound are constant and then if upper >= lower
934  * \param l loop to check execution
935  * \return true if the loop is always executed at least once
936  */
938 {
940 }
941 
942 
944 {
945  bool return_val = false;
946  expression low = range_lower(r); int i_low;
947  expression up = range_upper(r); int i_up;
948  expression inc = range_increment(r); int i_inc;
952  if (i_inc > 0 && i_up < i_low) {
953  // Increasing case
954  return_val = true;
955  }
956  else if (i_inc < 0 && i_up > i_low) {
957  // Decreasing case
958  return_val = true;
959  }
960  }
961  return return_val;
962 }
963 
964 
965 /**
966  * \brief Check if loop bound are constant and then if upper < lower
967  * \param l loop to check execution
968  * \return true if the loop is never executed
969  * if we don't know return false
970  */
972 {
974 }
975 
976 
977 /**
978  * Check if variable v is an index for an enclosing loop
979  */
980 bool index_of_a_loop_p( Variable v, list /* of statements */ loops )
981 {
982  bool result = false;
983  FOREACH(statement, s, loops) {
984  loop l = statement_loop(s);
985  pips_debug(5,"Enclosed loop with index : %s\n",entity_name(loop_index(l)));
986  if( same_entity_p((entity)v,loop_index(l) ) ) {
987  result = true;
988  }
989  }
990 
991  if(result) pips_debug(4,"%s is a loop index !\n",entity_name((entity)v));
992  else pips_debug(4,"%s is not a loop index !\n",entity_name((entity)v));
993 
994  return result;
995 }
996 
997 /* @} */
static hash_table seen
static function to store whether a module has been seen during the recursive generation of the daVinc...
Definition: graph.c:85
clone_context make_clone_context(entity a1, entity a2, list a3, statement a4)
Definition: cloning.c:52
void free_clone_context(clone_context p)
Definition: cloning.c:19
bool instruction_consistent_p(instruction p)
Definition: ri.c:1124
loop make_loop(entity a1, range a2, statement a3, entity a4, execution a5, list a6)
Definition: ri.c:1301
bool statement_consistent_p(statement p)
Definition: ri.c:2195
bool range_consistent_p(range p)
Definition: ri.c:2014
instruction make_instruction(enum instruction_utype tag, void *val)
Definition: ri.c:1166
range make_range(expression a1, expression a2, expression a3)
Definition: ri.c:2041
static FILE * out
Definition: alias_check.c:128
statement clone_statement(statement s, clone_context cc)
clone_statement.c
static list loops
#define region
simulation of the type region
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
Definition: statement.c:597
#define CONTROL_MAP(ctl, code, c, list)
Macro to walk through all the controls reachable from a given control node of an unstructured.
statement get_current_module_statement(void)
Get the current module statement.
Definition: static.c:208
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
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
bool assignment_block_p(instruction i)
Checks if an instruction block is a list of assignments, possibly followed by a continue.
Definition: instruction.c:230
set distributable_loop(statement l)
this functions checks if Kennedy's algorithm can be applied on the loop passed as argument.
Definition: loop.c:221
void print_number_of_loop_statistics(FILE *out, string msg, statement s)
Compute the number of parallel and sequential loops found in a statement and output them on a stream ...
Definition: loop.c:803
set region_of_loop(statement l)
this function returns the set of all statements belonging to the given loop even if the loop contains...
Definition: loop.c:254
bool range_contains_at_least_one_point_p(range r)
Definition: loop.c:911
static void loop_update_statistics(loop l)
Definition: loop.c:763
static int npar
Definition: loop.c:760
bool loop_sequential_p(loop l)
Test if a loop is sequential.
Definition: loop.c:404
bool loop_parallel_p(loop l)
Test if a loop is parallel.
Definition: loop.c:393
bool loop_executed_never_p(loop l)
Check if loop bound are constant and then if upper < lower.
Definition: loop.c:971
bool parallel_loop_statement_p(statement s)
Test if a statement is a parallel loop.
Definition: loop.c:420
static void loop_sort_locals(loop l)
Definition: loop.c:375
bool constant_step_loop_p(loop l)
Test if a loop has a constant step loop.
Definition: loop.c:733
bool normal_loop_p(loop l)
Test if a loop does have a 1-increment step.
Definition: loop.c:741
entity perfectly_nested_loop_index_at_depth(statement s, int depth)
Get the index of the loop at a given depth inside a loop-nest.
Definition: loop.c:694
static bool distributable_statement_p(statement stat, set region)
Definition: loop.c:176
static void rloops_mapping_of_unstructured(statement_mapping m, list loops, unstructured u)
Definition: loop.c:80
bool loop_executed_at_least_once_p(loop l)
Check if loop bound are constant and then if upper >= lower.
Definition: loop.c:937
static void rloops_mapping_of_statement()
statement make_new_loop_statement(entity i, expression low, expression up, expression inc, statement b, execution e)
This is an ad'hoc function designed for do_loop_unroll_with_epilogue().
Definition: loop.c:839
int loop_increment_value(loop l)
Definition: loop.c:714
statement perfectly_nested_loop_to_body(statement loop_nest)
Extract the body of a perfectly nested loop body.
Definition: loop.c:590
static int nseq
To store the number of sequential and parallel loops.
Definition: loop.c:760
bool index_private_p(loop lo)
returns true if loop lo's index is private for this loop
Definition: loop.c:240
void clean_enclosing_loops(void)
Definition: loop.c:58
int depth_of_perfect_loop_nest(statement s)
Compute the depth of a perfect loop-nest.
Definition: loop.c:476
statement perfectly_nested_loop_to_body_at_depth(statement s, int depth)
Extract the loop-body of a perfect loop-nest at a given depth.
Definition: loop.c:646
list copy_loops(list ll)
Duplicate a loop list.
Definition: loop.c:826
void region_of_statement(statement stat, set region)
Should be rewritten with a gen_recurse to deal with the recent RI...
Definition: loop.c:269
list loop_private_variables_as_entites(loop obj, bool local, bool index)
Get the variables local or private to a loop.
Definition: loop.c:338
void sort_all_loop_locals(statement s)
Definition: loop.c:381
bool range_contains_nothing_p(range r)
Definition: loop.c:943
list statement_to_loop_statement_list(statement s)
If statement s is a perfectly loop nest, return the corresponding loop list.
Definition: loop.c:893
void print_parallelization_statistics(const char *module, const char *msg, statement s)
Print out the number of sequential versus parallel loops.
Definition: loop.c:814
void number_of_sequential_and_parallel_loops(statement stat, int *pseq, int *ppar)
Compute the number of parallel and sequential loops found in a statement and update given variables.
Definition: loop.c:784
int Nbrdo
loop.c
Definition: loop.c:54
bool index_of_a_loop_p(Variable v, list loops)
Check if variable v is an index for an enclosing loop.
Definition: loop.c:980
statement get_first_inner_perfectly_nested_loop(statement stat)
Return the inner loop in a perfect loop-nest.
Definition: loop.c:508
statement_mapping loops_mapping_of_statement(statement stat)
Definition: loop.c:155
bool perfectly_nested_loop_p(statement stat)
Test if a statement is a perfect loop-nest.
Definition: loop.c:543
int depth_of_parallel_perfect_loop_nest(statement s)
Compute the depth of a parallel perfect loop-nest.
Definition: loop.c:436
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
void gen_remove(list *cpp, const void *o)
remove all occurences of item o from list *cpp, which is thus modified.
Definition: list.c:685
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
list gen_copy_seq(list l)
Copy a list structure.
Definition: list.c:501
size_t gen_length(const list l)
Definition: list.c:150
void gen_list_and_not(list *a, const list b)
Compute A = A inter non B:
Definition: list.c:963
#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
void * gen_find_eq(const void *item, const list seq)
Definition: list.c:422
#define MAPL(_map_list_cp, _code, _l)
Apply some code on the addresses of all the elements of a list.
Definition: newgen_list.h:203
#define 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
list gen_full_copy_list(list l)
Copy a list structure with element copy.
Definition: list.c:535
list statement_block(statement)
Get the list of block statements of a statement sequence.
Definition: statement.c:1338
loop statement_loop(statement)
Get the loop of a statement.
Definition: statement.c:1374
bool statement_loop_p(statement)
Definition: statement.c:349
bool continue_statement_p(statement)
Test if a statement is a CONTINUE, that is the FORTRAN nop, the ";" in C or the "pass" in Python....
Definition: statement.c:203
bool assignment_statement_p(statement)
Test if a statement is an assignment.
Definition: statement.c:135
bool declaration_statement_p(statement)
Had to be optimized according to Beatrice Creusillet.
Definition: statement.c:224
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
void hash_put(hash_table htp, const void *key, const void *val)
This functions stores a couple (key,val) in the hash table pointed to by htp.
Definition: hash.c:364
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
bool hash_defined_p(const hash_table htp, const void *key)
true if key has e value in htp.
Definition: hash.c:484
bool expression_constant_p(expression)
HPFC module by Fabien COELHO.
Definition: expression.c:2453
#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
int get_debug_level(void)
GET_DEBUG_LEVEL returns the current debugging level.
Definition: debug.c:67
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
#define SET_STATEMENT_MAPPING(map, stat, val)
Definition: newgen-local.h:47
#define DEFINE_CURRENT_MAPPING(name, type)
Definition: newgen-local.h:58
#define MAKE_STATEMENT_MAPPING()
Definition: newgen-local.h:43
#define STATEMENT_MAPPING_MAP(s, v, code, h)
Definition: newgen-local.h:53
@ hash_pointer
Definition: newgen_hash.h:32
#define set_undefined
Definition: newgen_set.h:48
void set_free(set)
Definition: set.c:332
@ 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
int tag
TAG.
Definition: newgen_types.h:92
bool EvalNormalized(normalized n, int *pv)
Definition: normalize.c:404
static char * module
Definition: pips.c:74
#define instruction_block_p(i)
#define NORMALIZE_EXPRESSION(e)
#define statement_block_p(stat)
#define unstructured_control
After the modification in Newgen: unstructured = entry:control x exit:control we have create a macro ...
#define is_instruction_block
soft block->sequence transition
#define instruction_block(i)
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
entity entity_empty_label(void)
Definition: entity.c:1105
void sort_list_of_entities(list l)
sorted in place.
Definition: entity.c:1358
void print_entities(list l)
Definition: entity.c:167
bool extended_integer_constant_expression_p_to_int(expression e, int *result)
Definition: expression.c:874
void free_enclosing_loops_map(void)
statement_mapping get_enclosing_loops_map(void)
#define value_undefined_p(x)
Definition: ri.h:3017
#define loop_body(x)
Definition: ri.h:1644
#define loop_execution(x)
Definition: ri.h:1648
#define loop_undefined
Definition: ri.h:1612
#define syntax_reference(x)
Definition: ri.h:2730
#define instruction_loop_p(x)
Definition: ri.h:1518
#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 instruction_loop(x)
Definition: ri.h:1520
#define value_unknown_p(x)
Definition: ri.h:3077
#define test_false(x)
Definition: ri.h:2837
#define range_increment(x)
Definition: ri.h:2292
#define entity_undefined
Definition: ri.h:2761
@ is_instruction_goto
Definition: ri.h:1473
@ is_instruction_unstructured
Definition: ri.h:1475
@ is_instruction_whileloop
Definition: ri.h:1472
@ is_instruction_expression
Definition: ri.h:1478
@ is_instruction_test
Definition: ri.h:1470
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_forloop
Definition: ri.h:1477
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define execution_sequential_p(x)
Definition: ri.h:1208
#define entity_name(x)
Definition: ri.h:2790
#define test_true(x)
Definition: ri.h:2835
#define instruction_forloop(x)
Definition: ri.h:1538
#define instruction_call_p(x)
Definition: ri.h:1527
#define loop_locals(x)
Definition: ri.h:1650
#define instruction_whileloop(x)
Definition: ri.h:1523
#define range_lower(x)
Definition: ri.h:2288
#define whileloop_body(x)
Definition: ri.h:3162
#define statement_declarations(x)
Definition: ri.h:2460
#define statement_instruction(x)
Definition: ri.h:2458
#define loop_range(x)
Definition: ri.h:1642
#define control_statement(x)
Definition: ri.h:941
#define instruction_test(x)
Definition: ri.h:1517
#define statement_number(x)
Definition: ri.h:2452
#define expression_syntax(x)
Definition: ri.h:1247
#define execution_parallel_p(x)
Definition: ri.h:1211
#define forloop_body(x)
Definition: ri.h:1372
#define instruction_unstructured(x)
Definition: ri.h:1532
#define loop_index(x)
Definition: ri.h:1640
#define statement_undefined
Definition: ri.h:2419
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
#define entity_initial(x)
Definition: ri.h:2796
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
#define ifdebug(n)
Definition: sg.c:47
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
struct cons * cdr
The pointer to the next element.
Definition: newgen_list.h:43
Definition: statement.c:54
static int depth
la sequence de nids
void * Variable
arithmetique is a requirement for vecteur, but I do not want to inforce it in all pips files....
Definition: vecteur-local.h:60