PIPS
statement.c
Go to the documentation of this file.
1 /*
2 
3  $Id: statement.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  /*
28  Function for statement, and its subtypes:
29  - instruction
30 
31  Lei ZHOU 12 Sep. 1991
32  Francois IRIGOIN
33  */
34 
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <stdlib.h>
39 #include <stdarg.h>
40 
41 #include "linear.h"
42 #include "genC.h"
43 
44 #include "misc.h"
45 #include "properties.h"
46 
47 #include "ri-util.h"
48 
49 /* Conditional execution is used to mask the call to MakeSimpleIoInst2.
50  *
51  * It is preserved because the current validation suite does not
52  * include test cases covering its replacement.
53  *
54  * #include "syntax.h" // MakeSimpleIoInst2
55  */
56 
57 /** @defgroup statement_util Methods dealing with statements
58  @{
59 */
60 
61 /******************************************************* EMPTY STATEMENT */
62 /* detects a statement with no special effect...
63  */
64 
65 
66 /** @defgroup statement_predicate Statement predicate methods
67  @{
68 */
69 
70 static bool cannot_be_empty(bool *statement_is_empty)
71 {
72  gen_recurse_stop(NULL);
73  return *statement_is_empty = false;;
74 }
75 
76 static bool call_filter(call c,bool *statement_is_empty)
77 {
78  entity e = call_function(c);
80  return false;
81  else
82  return cannot_be_empty(statement_is_empty);
83 }
84 
85 bool
87 {
88  if ((!s) || statement_undefined_p(s))
89  return true;
90 
91  bool statement_is_empty = true;
92  gen_context_recurse(s,&statement_is_empty, call_domain, call_filter, gen_null2);
93 
94  pips_debug(3, "returning %d\n", statement_is_empty);
95 
96  return statement_is_empty;
97 }
98 
100 {
101  MAP(STATEMENT, s, if (!empty_code_p(s)) return false, l);
102  return true;
103 }
104 
105 
106 bool
107 empty_comments_p(const char* s)
108 {
109  /* Could be replaced by a macro. See macro empty_comments */
110  pips_assert("comments cannot be NULL", s!=NULL);
111  return (string_undefined_p(s) || strcmp(s,"")==0);
112 }
113 
114 
115 bool
116 comments_equal_p(string c1, string c2)
117 {
118  return
119  ( empty_comments_p(c1) && empty_comments_p(c2)) ||
120  (!empty_comments_p(c1) && !empty_comments_p(c2) && same_string_p(c1,c2));
121 }
122 
123 
124 /* Return true if the statement has an empty statement: */
125 bool
127 {
128  string the_comments = statement_comments(s);
129  return empty_comments_p(the_comments);
130 }
131 
132 
133 /* Test if a statement is an assignment. */
134 bool
137 
138  return instruction_assign_p(i);
139 }
140 
141 
143 {
145 
146  switch(instruction_tag(i)) {
149  break;
150  case is_instruction_test:
151  break;
152  case is_instruction_loop:
153  break;
155  break;
156  case is_instruction_goto:
157  pips_internal_error("unexpected GO TO");
158  break;
159  case is_instruction_call:
160  return assignment_statement_p(s);
162  break;
163  default:
164  pips_internal_error("ill. instruction tag %d", instruction_tag(i));
165  break;
166  }
167  return false;
168 }
169 
170 
171 /* Test if a statement is a C or Fortran "return" */
174  return return_instruction_p(i);
175 }
176 
179  return exit_instruction_p(i);
180 }
181 
184  return abort_instruction_p(i);
185 }
186 
187 /* Test if a statement is a Fortran "return" */
191 }
192 
193 /* Test if a statement is a C "return" */
196  return C_return_instruction_p(i);
197 }
198 
199 
200 /* Test if a statement is a CONTINUE, that is the FORTRAN nop, the ";" in
201  C or the "pass" in Python... according to the language.
202 */
205 
206  return instruction_continue_p(i);
207 }
208 
211 
212  return instruction_forloop_p(i);
213 }
214 
215 /* Had to be optimized according to Beatrice Creusillet. We assume
216  that false is returned most of the time. String operations are
217  avoided (almost) as much as possible.
218 
219  For the time being a declaration statement is a call to continue
220  with non-empty declarations.
221 
222  FI: This could be fixed by adding + declaration in the instruction domainn
223 */
225  bool declaration_p = false;
226 
227  /* Initial implementation. It would have been better to check
228  !ENDP() first. */
229  //return instruction_continue_p(i) &&
230  //!ENDP(statement_declarations(s));
231 
232  if(!ENDP(statement_declarations(s))) {
234  if(instruction_call_p(i)) {
235  call c = instruction_call(i);
236  entity f = call_function(c);
237  declaration_p = entity_continue_p(f);
238  }
239  }
240 
241  return declaration_p;
242 }
243 
244 /* Check that all statements contained in statement list sl are a
245  continue statements. */
247 {
248  bool continue_p = true;
249 
250  FOREACH(STATEMENT, s, sl) {
251  if(!continue_statement_p(s)) {
252  continue_p = false;
253  break;
254  }
255  }
256 
257  return continue_p;
258 }
259 
260 
261 /* Test if a statement is a Fortran STOP.
262 */
264 {
266 
267  return instruction_stop_p(i);
268 }
269 
270 
271 /* Test if a statement is a Fortran FORMAT.
272 */
274 {
276 
277  return instruction_format_p(i);
278 }
279 
280 
282 {
284 
286 }
287 ␌
289 {
290  int o1 = statement_ordering( st1 ) ;
291  int o2 = statement_ordering( st2 ) ;
292 
293  if (ORDERING_NUMBER( o1 ) != ORDERING_NUMBER( o2 )) {
294  fprintf(stderr, "cannot compare %td (%d,%d) and %td (%d,%d)\n",
295  statement_number(st1),
296  ORDERING_NUMBER( o1 ), ORDERING_STATEMENT( o1 ),
297  statement_number(st2),
298  ORDERING_NUMBER( o2 ), ORDERING_STATEMENT( o2 ));
299 
300  abort();
301  }
302 
303  return( ORDERING_STATEMENT(o1) < ORDERING_STATEMENT(o2)) ;
304 }
305 
307 {
308  int o1 = statement_ordering( st1 ) ;
309  int o2 = statement_ordering( st2 ) ;
310 
311  if (ORDERING_NUMBER( o1 ) != ORDERING_NUMBER( o2 )) {
312  return(true);
313  }
314  else
315  return( ORDERING_STATEMENT(o1) < ORDERING_STATEMENT(o2));
316 }
317 
318 
319 /* @defgroup statement_2nd_access_test Direct test of the instruction
320  type of statement
321 
322  With these methods you can directly test the type of the instruction
323  inside a statement
324 
325  @{
326 */
327 
328 /* Statement classes induced from instruction type
329  *
330  * Naming conflict between English, block_statement_p(), and NewGen convention
331  * isntruction_loop_p()
332  */
333 
334 /* See also macro statement_block_p() */
336 {
338  bool r = instruction_sequence_p(i);
339 
340  return r;
341 }
342 
344 {
346 }
347 
348 
350 {
352 }
353 
355 {
357 }
358 
360 {
362 }
363 
365 {
367 }
368 
370 {
372 }
373 
375 {
377 }
378 
380 {
382 }
383 
385 {
387 }
388 
389 
390 /* Test if a statement is empty. */
392 {
393  instruction i;
394 
395  return(unlabelled_statement_p(st) &&
397  ENDP(instruction_block(i)) &&
399 }
400 
401 
403 {
405 }
406 
408 {
409  /* NOP statements are useful to fill in empty test branches.
410  * The definition of NOP in PIPS has changed over the years.
411  * A NOP statement is an empty block. Like blocks, it cannot be
412  * labelled nor commented. It has no statement number because it
413  * is invisible to users.
414  *
415  * Dangling comments, like labels, are attached to CONTINUE statements.
416  *
417  * Note 1: blocks are now called "sequences"
418  * Note 2: see also empty_statement_p()
419  */
420  bool nop = false;
422 
424  pips_assert("No label!", unlabelled_statement_p(s));
425  pips_assert("No comments", empty_comments_p(statement_comments(s)));
426  pips_assert("No statement number",
428  nop = true;
429  }
430 
431  return nop;
432 }
433 
434 /* Return true if the statement is an empty instruction block without
435  label or a continue without label or a recursive combination of
436  above.
437 
438  FI: I add a check on declarations. With their initializations, they
439  have side effects. See C_syntax/block01.c.
440 
441  FI: same issue with CONTINUE.
442 
443  If there is an extension on it (such as a pragma) return false since
444  this statement may be useful/
445  */
447 {
448  instruction i;
449 
450  if (!unlabelled_statement_p(st)
452  return false;
453 
454  if (continue_statement_p(st))
455  return ENDP(statement_declarations(st));
456 
457  i = statement_instruction(st);
459  MAP(STATEMENT, s,
460  {
462  /* Well there is at least one possibly usefull thing... */
463  return false;
464  },
465  instruction_block(i));
466  return true;
467  }
468  return false;
469 }
470 
471 
472 /* Return true if the statement is an empty instruction block or a
473  continue or a recursive combination of above. */
475 {
476  instruction i;
477 
478  if (continue_statement_p(st))
479  return true;
480  i = statement_instruction(st);
481  if (instruction_block_p(i)) {
483  {
485  /* Well there is at least one possibly usefull thing... */
486  return false;
487  }
488  return true;
489  }
490  return false;
491 }
492 
493 
494 /* Return true if the statement is an empty instruction block or a
495  continue without comments or without LABEL or without declarations
496  or a recursive combination of above. */
498 {
499  instruction i;
500  string the_comments = statement_comments(st);
501 
502  /* The very last condition should be sufficient */
503  if (!empty_comments_p(the_comments))
504  return false;
505 
506  if (!unlabelled_statement_p(st))
507  return false;
509  return true;
510 
511  i = statement_instruction(st);
512  if (instruction_block_p(i)) {
513  MAP(STATEMENT, s,
514  {
516  return false;
517  },
518  instruction_block(i));
519  /* Everything in the block are commentless continue or empty
520  statements: */
521  return true;
522  }
523  /* Everything else useful: */
524  return false;
525 }
526 
527 
529 {
530  bool check_io = false;
532 
533  if(instruction_test_p(i)) {
535 
536  if(syntax_reference_p(c)) {
538  }
539  }
540 
541  return check_io;
542 }
543 
544 /** @} */
545 
546 /* functions to generate statements */
547 
548 
549 /* Duplicate statement comments
550 
551  @param comment is the comment to duplicate
552 
553  @return the duplicated comment. If it was an allocated string, it is
554  strdup()ed
555 */
556 string
558  if (comment == NULL || string_undefined_p(comment))
559  /* Not allocated, just the same: */
560  return comment;
561  else
562  return strdup(comment);
563 }
564 
565 
566 /* Duplicate statement decls_text
567 
568  @param dt is the decls_text to duplicate
569 
570  @return the duplicated decls_text. If it was an allocated string, it is
571  strdup()ed
572 */
573 string
574 decls_text_dup(string dt) {
575  if (dt == NULL)
576  /* Not allocated, just the same: */
577  return dt;
578  else
579  return strdup(dt);
580 }
581 
582 
584  expression r)
585 {
587 }
588 
589 
590 /** @defgroup block_statement_constructors Block/sequence statement constructors
591  @{
592  */
593 
594 /** Build a statement from a give instruction
595 */
596 statement
598  return(
604  instr,
605  NIL,
609  )
610  );
611 }
612 
613 
614 /** Make a block statement from a list of statement
615  */
617  statement b;
618 
620  return b;
621 }
622 
623 
624 /** Build an empty statement (block/sequence)*/
627  return b;
628 }
629 
630 
631 /**
632  * Build an empty statement with declaration list, declaration text
633  * and comment. Shouldn't we also update the extensions field?
634  * Can we really make an non empty_comment for block?
635  * cf text_statement_enclosed() or clean_up_sequences_rewrite()
636  * "block statement should be labelless, numberless and commentless"
637  */
639  string dt,
640  string c) {
643  statement_decls_text(s) = dt;
644  statement_comments(s) = c;
645  return s;
646 }
647 
648 
649 /* Move all the attributes from one statement to another one.
650 
651  Do not copy the instruction
652 
653  @param from is the statement we pick the attributes from
654 
655  @param to is the statement we copy the attributes into
656 */
658  statement to) {
659  statement_label(to) = statement_label(from);
663  //statement_instruction(to) = statement_instruction(from);
667 }
668 
669 
670 /* Copy all the attributes from one statement to another one.
671 
672  Do not copy the instruction
673 
674  @param from is the statement we pick the attributes from
675 
676  @param to is the statement we copy the attributes into
677 */
679  statement to) {
680  statement_label(to) = statement_label(from);
684  //statement_instruction(to) = statement_instruction(from);
688 }
689 
690 
691 /** Build a statement sequence from a statement list
692 
693  @param[in] l is the statement list
694 
695  @return the statement if there is only 1 statement in the list l or
696  build a block from the statement list. So, if the list was NIL, this
697  makes an empty statement block.
698 */
699 statement
701  if (gen_length(l) == 1) {
702  statement stat = STATEMENT(CAR(l));
703  gen_free_list(l);
704  return stat;
705  }
706  else
707  return make_block_statement(l);
708 }
709 
710 
711 /** Build a statement sequence from a statement list
712 
713  @return :
714  - statement_undefined if the statement list is NIL
715  - the statement of a list with one statement, after discarding the list
716  - a statement block with the statement list else.
717 */
718 statement
720  if (l == NIL)
721  return statement_undefined;
722  else
724 }
725 
726 
727 /** Build a statement sequence from a statement NULL-terminated varargs list
728 
729  It is called with
730  make_statement_from_statement_varargs_list(s1, s2,..., sn, NULL)
731 
732  @return a statement block with the statement list
733 */
734 statement
736  va_list args;
737  /* The statement list */
738  list sl = NIL;
739 
740  /* Analyze in args the variadic arguments that may be after s: */
741  va_start(args, s);
742  /* Since a variadic function in C must have at least 1 non variadic
743  argument (here the s), just skew the varargs analysis: */
744  for(;;) {
745  if (s == NULL)
746  /* No more statement */
747  break;
748  /* Use an O(n2) algorithm that would be enough to concatenate few
749  statements */
750  sl = gen_nconc(sl, CONS(STATEMENT, s, NIL));
751  /* Get the next argument: */
752  s = va_arg(args, statement);
753  }
754  /* Release the variadic analyzis: */
755  va_end(args);
756 
757  /* Build a statement block from a normal list: */
758  return make_block_statement(sl);
759 }
760 
761 
762 /** Build a statement block from a statement if not already a statement
763  block.
764 
765  @return the new block statement or the old statement
766  */
767 statement
770  /* It is already a block statement */
771  return stmt;
772  else
774 }
775 
776 /** @} */
777 
778 
780 {
781  const char *module_name = entity_local_name(module);
785 }
786 
787 /*****************************************************************************
788 
789  Make a Fortran io statement : PRINT *,"message" following this format :
790 BEL_PREFIX
791  (keyword,lci,lio)
792 
793  keyword (READ, WRITE, PRINT...).
794 
795  lci is a list of 'control specifications'. its has the following format:
796  ("UNIT=", 6, "FMT=", "*", "RECL=", 80, "ERR=", 20)
797  default : * = LIST_DIRECTED_FORMAT_NAME
798 
799  lio is the list of expressions to write or references to read.
800  ("IOLIST=", exp, ...)
801 
802 *****************************************************************************/
803 /* Derived from the Fortran parser code
804  *
805  * Should be generalized to generate C code...
806  */
808  expression f,
809  list io_list)
810 {
815 
816  list cil = CONS(EXPRESSION, unit,
817  CONS(EXPRESSION, std,
818  CONS(EXPRESSION, format,
819  CONS(EXPRESSION, f, NULL))));
820 
821  // Initial implementation:
822  // inst = MakeIoInstA((keyword==TK_PRINT)?TK_WRITE:TK_READ,
823  // cil, io_list);
824 
825  list lci = gen_nconc(cil, io_list);
826 
829  instruction io_call = make_instruction_call(make_call(op, lci));
830 
831  return io_call;
832 }
833 
834 /* Make a Fortran print statement*/
836 {
840  list args = CONS(EXPRESSION,e1,CONS(EXPRESSION,e2,NIL));
841  /* This function has been moved from alias_check.c and uses a
842  Fortran only function. alias_check was designed from Fortran. */
844 #if 1
845  ins = make_simple_Fortran_io_instruction(false,fmt,args);
846 #else
847  ins = MakeSimpleIoInst2(301,fmt,args);
848 #endif
849  return instruction_to_statement(ins);
850 }
851 
853 {
855  list args = NIL;
856  /* MakeConstant() generates a Fortran constant... Does not seem
857  to matter for strings... */
858  expression eb =
861  STDERR_NAME);
863 
864  if(entity_undefined_p(lun)) {
865  /* stderr has not yet been encountered by the parser... Should
866  it be defined by bootstrap.c or by the C parser no matter
867  what? */
868  lun = make_stderr_variable();
869  }
870  ea = entity_to_expression(lun);
871 
872  args = CONS(EXPRESSION,ea, CONS(EXPRESSION,eb,NIL));
874  args,
877  return s;
878 }
879 
880 /* Generate a print of a constant character string on stderr for C or
881  on stdout for Fortran.
882 
883  This is not clever as the format of the message is language
884  dependent: simple quotes are used as delimiters in Fortran and
885  double quotes in C. Should message be language independent and the
886  delimiters added in this function instead? I did not do it to avoid
887  yet another strdup() when strdup is used to generate "message", but
888  this is questionable.
889 
890  This is not clever as this function could easily be generalized
891  with a vararg to generate more general print statements.
892 */
894 {
897 
898  if(fortran_module_p(m))
900  else
902 
903  return s;
904 }
905 
906 /* This function returns a Fortran stop statement with an error message
907  */
909 {
910  list args=NIL;
911  expression e;
912 
914 
915  args = CONS(EXPRESSION,e,NIL);
916 
918 
919 }
920 
921 /* This function returns a statement ending with a C exit statement. A
922  "fprintf(stderr, errmess);" is generated before "exit(n);" if
923  errmess is not empty and a sequence statement ending wih exit() is
924  returned.
925  */
926 statement make_exit_statement(int n, string errmess)
927 {
931  list args1 = CONS(EXPRESSION,e1,NIL);
932 
934  args1,
937 
938  if(strlen(errmess)>0) {
939  statement s2 = make_C_print_statement(errmess);
940  /* There must be a nicer vararg
941  function... make_statement_from_statement_varargs_list(s2, s1, NULL) */
943  }
944  else
945  s = s1;
946 
947  return s;
948 
949 }
950 
951 
952 
954 {
957 }
958 
959 
960 /* Make a simple continue statement to be used as a NOP or ";" in C
961 
962  @return the statement
963 */
965 {
967 }
968 
969 
970 /* Make a declaration(s) statement
971 
972  To preserve declaration lines and comments, declaration statements are
973  used
974 
975  @param idl is a sorted list of variables that is copied and
976  modified for insertion in the declaration. The order is
977  preserved. No sharing is created between idl and s.
978 
979  @param sn is the statement number
980 
981  @param cs is the comment string associated to the declaration
982 
983  Note that additional information is dangerously hidden later as
984  arguments to the call to CONTINUE.
985 
986  Note also that this function is closely linked to the C parser but
987  is unfortunately used by transformations/registers.c in a much
988  simpler form.
989  */
991 {
993 
994  /* If a place holder variable has been inserted by the C parser, it
995  may be uselss. If several place holder variables have been
996  inserted, they certainly are useless. */
997  list l = NIL;
998  if(gen_length(idl)>2) {
999  FOREACH(ENTITY, v, idl) {
1000  if(!place_holder_variable_p(v))
1001  l = CONS(ENTITY, v, l);
1002  else {
1003  // FI: the variable should be removed
1004  // free_entity(v);
1005  ;
1006  // FI: as well as its initialization expression :-(
1007  ;
1008  }
1009  }
1010  l = gen_nreverse(l);
1011  // Do not free idl because it is re-used later... by the C parser
1012  // gen_free_list(idl);
1013  }
1014  else {
1015  /* Do not create sharing with the caller */
1016  l = gen_copy_seq(idl);
1017  }
1018 
1019  /* Remove useless place holder entities if any */
1020 
1021  /* Build the list of derived entities defined.
1022  *
1023  * A derived entity is defined if its fields or elements appear in
1024  * "l". Otherwise, it is simply referenced in the definition of
1025  * another derived entity. Or it is simply "mentioned" as in "struct
1026  * s;". Such statements can move around and do not really require
1027  * strong dependences. See our 2015 LCPC paper.
1028  *
1029  */
1030  /* list defined_l = NIL; */
1031  /* FOREACH(ENTITY, e, l) { */
1032  /* if(derived_entity_p(e)) { */
1033  /* type dt = entity_type(e); */
1034  /* list fl = NIL; */
1035  /* if(type_struct_p(dt)) */
1036  /* fl = type_struct(dt); */
1037  /* else if(type_union_p(dt)) */
1038  /* fl = type_union(dt); */
1039  /* else if(type_enum_p(dt)) */
1040  /* fl = type_enum(dt); */
1041  /* else */
1042  /* pips_internal_error("Unexpected type for a derived entity.\n"); */
1043  /* if(!ENDP(fl)) {// The derived type may not yet be fully defined */
1044  /* entity f = ENTITY(CAR(fl)); */
1045  /* if(gen_in_list_p(f, l)) */
1046  /* defined_l = CONS(ENTITY, e, defined_l); */
1047  /* } */
1048  /* } */
1049  /* } */
1050 
1051  /* Remove field entities from the declaration list and make sure
1052  that each derived entity is declared at most once, and really
1053  declared */
1054  list dl = NIL;
1055  if(!ENDP(l)) {
1056  list cl = CDR(l);
1057  FOREACH(ENTITY, e, l) {
1058  if(!entity_field_p(e)) { // Fields are declared via derived entities
1059  if(!gen_in_list_p(e, cl)) // Do not declare entities more than once
1060  /* && (!derived_entity_p(e) || gen_in_list_p(e, defined_l))) // Declare only defined derived entities and all other kinds of entities */
1061  dl = CONS(ENTITY, e, dl);
1062  }
1063  if(!ENDP(cl))
1064  cl = CDR(cl);
1065  }
1066  dl = gen_nreverse(dl);
1067  }
1068  /* gen_free_list(defined_l); */
1069 
1070  /* if(ENDP(dl)) { */
1071  /* if(!ENDP(l)) { */
1072  /* /\* Must be a case such as "struct s;" *\/ */
1073  /* entity de = ENTITY(CAR(l)); */
1074  /* if(derived_entity_p(de)) { */
1075  /* entity ph = make_place_holder_variable(de); */
1076  /* dl = CONS(ENTITY, ph, NIL); */
1077  /* } */
1078  /* } */
1079  /* else */
1080  /* pips_internal_error("Empty declaration_list.\n"); */
1081  /* } */
1082 
1083  statement_declarations(ds) = dl;
1084  statement_number(ds) = sn;
1085  statement_comments(ds) = cs;
1086  return ds;
1087 }
1088 
1089 /* Make *one* declaration statement.
1090  */
1092 {
1093  return make_declarations_statement(CONS(ENTITY, v, NIL), sn, cs);
1094 }
1095 
1096 
1097 /* Check that all statements contained in statement list sl are
1098  declaration statements. */
1100 {
1101  bool declaration_p = true;
1102 
1103  FOREACH(STATEMENT, s, sl) {
1104  if(!declaration_statement_p(s)) {
1105  declaration_p = false;
1106  break;
1107  }
1108  }
1109 
1110  return declaration_p;
1111 }
1112 
1113 /* The initialization expression list is integrated into the internal
1114  * representation as an argument list.
1115  *
1116  * For the time being, I am cheating because its a list of integer and
1117  * not a list of expressions.
1118  */
1120 {
1121  pips_assert("s is a declaration statement", declaration_statement_p(s));
1123  pips_assert("No arguments", ENDP(call_arguments(c)));
1124  call_arguments(c)= iel;
1125  return s;
1126 }
1127 
1129 {
1130  pips_assert("s is a declaration statement", declaration_statement_p(s));
1132  list iel = call_arguments(c);
1133  return iel;
1134 }
1135 
1136 
1137 /* Build a while loop statement.
1138 
1139  If \a before is true, build a
1140  while (\a condition)
1141  \a body;
1142 
1143  else build a
1144  do
1145  \a body;
1146  while (\a condition);
1147 
1148  @param line_number is used to specify a source-line number to the statement
1149 */
1151  statement body,
1152  int line_number,
1153  bool before) {
1154  whileloop w;
1155  statement smt;
1156 
1157  w = make_whileloop(condition, body, entity_empty_label(),
1160  line_number,
1162  //pop_current_C_comment(),
1167  return smt;
1168 }
1169 
1170 /**
1171  * Build a loop statement
1172  * \param i index of the loop
1173  * \param low lower bound of the loop (an int expression)
1174  * \param up upper bound of the loop (an int expression)
1175  * \param inc increment step of the loop (an int expression)
1176  * \param b body of the loop
1177  * \return a loop statement with the condition low<i<up, with step inc and body b
1178  * see also make_new_loop_statement
1179  * Unlike make_new_loop_statement, make_loop_statement doesn't clone the body
1180  */
1182  entity i,
1183  expression low,
1184  expression up,
1185  expression inc,
1186  statement b)
1187 {
1188  /* Loop range is created */
1189  range rg = make_range(low, up, inc);
1190  ifdebug(9) {
1191  pips_assert("new range is consistent", range_consistent_p(rg));
1192  }
1193 
1194  loop l = make_loop(
1195  i,
1196  rg,
1197  b,
1200  NIL);
1201 
1208  NIL,
1210  empty_extensions(),
1212  ifdebug(9) {
1213  pips_assert("stmt is consistent",
1215  }
1216 
1217  return stmt;
1218 }
1219 
1221  forloop l = make_forloop(
1222  init,
1223  cond,
1224  inc,
1225  body);
1226  ifdebug(9) {
1227  pips_assert("new forloop is consistent", forloop_consistent_p(l));
1228  }
1229 
1236  NIL,
1238  empty_extensions(),
1240  ifdebug(9) {
1241  pips_assert("stmt is consistent",
1243  }
1244 
1245  return stmt;
1246 }
1247 
1249  test t = make_test(cond, truebody, falsebody);
1250  ifdebug(9) {
1251  pips_assert("new test is consistent", test_consistent_p(t));
1252  }
1253 
1260  NIL,
1262  empty_extensions(),
1264  ifdebug(9) {
1265  pips_assert("stmt is consistent",
1267  }
1268 
1269  return stmt;
1270 }
1271 
1272 /* This function is limited to intrinsics calls... A full function
1273  name or an entity could be passed as first argument. */
1274 statement make_call_statement(function_name, args, l, c)
1275 string function_name;
1276 list args;
1277 entity l; /* label, default entity_undefined */
1278 string c; /* comments, default empty_comments (was: "" (was: string_undefined)) */
1279 {
1280  entity called_function;
1281  statement cs;
1282 
1283  called_function = entity_intrinsic(function_name);
1284 
1285  l = (l==entity_undefined)? entity_empty_label() : l;
1286  cs = make_statement(l,
1289  c,
1291  make_call(called_function,args)),
1292  NIL,
1293  NULL,
1295 
1296  // To avoid a cycle between ri-util and prettyprint
1297  /* ifdebug(8) { */
1298  /* pips_debug(8, "cs is call to %s\n", function_name); */
1299  /* safe_print_statement(cs); */
1300  /* } */
1301 
1302  return cs;
1303 }
1304 
1305 
1306 /** Build a statement from a given expression
1307  */
1309 {
1312 
1313  return s;
1314 }
1315 
1316 
1317 /* @defgroup statement_2nd_access_method Direct statement accessors to
1318  second level fields
1319 
1320  With these methods you can access directly to the inside of the
1321  instructions
1322 
1323  @{
1324 */
1325 
1326 /* Get the sequence of a statement sequence */
1327 sequence
1329 {
1330  pips_assert("statement_sequence", statement_sequence_p(s));
1331 
1333 }
1334 
1335 
1336 /* Get the list of block statements of a statement sequence */
1337 list
1339 {
1340  pips_assert("statement_sequence", statement_sequence_p(s));
1341 
1343 }
1344 
1345 
1346 /* Get the test of a statement */
1347 test
1349 {
1350  pips_assert("statement_test", statement_test_p(s));
1351 
1353 }
1354 
1355 /* returns the effective true branch of a test by skipping a possible
1356  sequence of one element. OK, this should be performed
1357  recursively... */
1359 {
1360  statement ets = test_true(t);
1361 
1362  if(statement_block_p(ets)) {
1363  list sl = statement_block(ets);
1364  if(gen_length(sl)==1) {
1365  ets = STATEMENT(CAR(sl));
1366  }
1367  }
1368 
1369  return ets;
1370 }
1371 
1372 /* Get the loop of a statement */
1373 loop
1375 {
1376  pips_assert("statement_loop", statement_loop_p(s));
1377 
1379 }
1380 
1381 
1382 /* Get the whileloop of a statement */
1384 {
1385  pips_assert("statement_whileloop", statement_whileloop_p(s));
1386 
1388 }
1389 
1390 
1391 /* Get the goto of a statement
1392 
1393  @return the statement pointed to by the "goto"
1394 */
1395 statement
1397 {
1398  pips_assert("statement_goto", statement_goto_p(s));
1399 
1401 }
1402 
1403 
1404 /* Get the call of a statement */
1405 call
1407 {
1408  pips_assert("statement_call", statement_call_p(s));
1409 
1411 }
1412 
1413 
1414 /* Get the unstructured of a statement */
1417 {
1418  pips_assert("statement_unstructured", statement_unstructured_p(s));
1419 
1421 }
1422 
1423 
1424 /* Get the forloop of a statement */
1425 forloop
1427 {
1428  pips_assert("statement s is a forloop", statement_forloop_p(s));
1429 
1431 }
1432 
1433 
1434 /* Get the multitest of a statement */
1435 multitest
1437 {
1438  pips_assert("statement_multitest", statement_multitest_p(s));
1439 
1441 }
1442 
1443 
1444 /* Get the expression of a statement */
1445 expression
1447 {
1448  pips_assert("statement_expression", statement_expression_p(s));
1449 
1451 }
1452 
1453 /* @} */
1454 
1455 
1456 ␌
1457 /* Mapping from statement number to statement
1458  *
1459  * Warning: STATEMENT_NUMBER_UNDEFINED may be equal to HASH_ENTRY_FREE_FOR_PUT
1460  *
1461  * Two statements in the same piece of code may have the same number because:
1462  * - they were generated by the parser to simulate a unique user statement
1463  * (e.g. a computed GO TO)
1464  * - they were generated by a program transformation from the same user
1465  * statement (e.g. DO statements by a loop distribution)
1466  *
1467  * A statement may be not numbered because:
1468  * - the parser assumed that it did not matter (e.g. a GO TO transformed into
1469  * an arc by the controlizer); but the parser is not really consistent...
1470  * - a program generation phase has no way to generate a realistic statement
1471  * number from a user statement number (e.g. code for banks in WP65)
1472  */
1473 
1474 /* static variable temporarily required to use gen_recurse() */
1476 /* To keep track of duplicate numbers */
1478 
1480 {
1483  != HASH_UNDEFINED_VALUE) {
1486  (char *) statement_number(s));
1487  }
1488  else {
1489  hash_put(number_to_statement, (char *) statement_number(s), (char *) s);
1490  }
1491  }
1492 }
1493 
1494 statement
1496 {
1497  /* This function used to be inline in prettyprinting functions for user views.
1498  * It was assumed that all statements produced by the parser had a defined
1499  * statement number. In order to keep a nice statement numbering scheme,
1500  * GO TO statements are not (always) numbered. So n hasa to be tested.
1501  */
1502 
1504 
1506  s = (statement) hash_get(nts, (char *) n);
1507  if (s == (statement) HASH_UNDEFINED_VALUE) {
1508  s = statement_undefined;
1509  }
1510  }
1511 
1512  return s;
1513 }
1514 
1515 hash_table
1517 hash_table nts;
1518 statement s;
1519 {
1520  pips_assert("build_number_to_statement", nts!=hash_table_undefined
1522 
1525 
1527 
1528  /* Eliminate duplicate and hence meaningless numbers */
1529  SET_MAP(n, {
1531  }, duplicate_numbers);
1532 
1533  /* nts is updated by side effect on number_to_statement */
1537  return nts;
1538 }
1539 
1541 {
1543 
1544  /* let's assume that 50 statements is a good approximation of a
1545  * module size.
1546  */
1547  nts = hash_table_make(hash_int, 50);
1548 
1549  return nts;
1550 }
1551 
1552 
1553 /** Get rid of all labels in controlized code before duplication
1554 
1555  All labels have become useless and they cannot be freely duplicated.
1556 
1557  One caveat: FORMAT statements!
1558 */
1559 statement
1562  clean_up_sequences(s);
1563  return s;
1564 }
1565 
1566 
1567 void
1569 statement s;
1570 {
1571  if(format_statement_p(s)) {
1572  user_error("clear_label", "Cannot clear label for FORMAT %s!\n",
1574  }
1575 
1577 
1581 }
1582 
1583 
1584 statement
1585 st_make_nice_test(condition, ltrue, lfalse)
1586 expression condition;
1587 list ltrue,lfalse;
1588 {
1589  statement
1590  stattrue = make_statement_from_statement_list(ltrue),
1591  statfalse = make_statement_from_statement_list(lfalse);
1592  bool
1593  notrue=(stattrue==statement_undefined),
1594  nofalse=(statfalse==statement_undefined);
1595 
1596  if ((notrue) && (nofalse))
1598 
1599  if (nofalse)
1600  {
1601  return
1605  make_test(condition,
1606  stattrue,
1608  }
1609 
1610  if (notrue)
1611  {
1612  expression
1614  condition);
1615 
1616  return
1620  make_test(newcond,
1621  statfalse,
1623  }
1624 
1626  make_test(condition,
1627  stattrue,
1628  statfalse))));
1629 }
1630 
1631 
1632 /* statement makeloopbody(l, s_old)
1633  * make a statement for a loop body, using the fields of a previously existing statement
1634  *
1635  * Preserving the labels may be sometimes a good thing (hyperplane or
1636  * tiling transformation, outermostloop) or a bad thing for innermost
1637  * loops, sometimes replicated loops
1638  *
1639  * FI: the name of this function is not well chosen.
1640  */
1641 statement makeloopbody(loop l, statement s_old, bool inner_p)
1642 {
1643  statement state_l;
1644  instruction instr_l;
1645  statement l_body;
1646 
1648  state_l = make_statement(inner_p? entity_empty_label() : statement_label(s_old),
1649  statement_number(s_old),
1650  statement_ordering(s_old),
1651  statement_comments(s_old),
1652  instr_l,NIL,NULL,
1659  NIL,NULL,
1661 
1662  return(l_body);
1663 }
1664 
1665 
1666 /* Does work neither with undefined statements nor with defined
1667  statements with undefined instructions. Returns a statement
1668  identity, its number and the breakdown of its ordering, as well as
1669  information about the instruction. */
1670 
1672 {
1673  string buffer;
1675  string instrstring = instruction_identification(i);
1676  int so = statement_ordering(s);
1677  entity called = entity_undefined;
1678 
1679  if(same_string_p(instrstring, "CALL")) {
1680  called = call_function(instruction_call(i));
1681  }
1682 
1683  int n = asprintf(&buffer, "%td (%d, %d): %s %s\n",
1684  statement_number(s),
1685  ORDERING_NUMBER(so),
1686  ORDERING_STATEMENT(so),
1687  instrstring,
1688  entity_undefined_p(called)? "" : module_local_name(called));
1689 
1690  pips_assert("asprintf ok", n!=-1);
1691 
1692  return buffer;
1693 }
1694 
1695 /* Like external_statement_identification(), but with internal
1696  information, the hexadecimal address of the statement
1697 
1698  Allocate a new string.
1699  */
1701 {
1702  char * buffer;
1704  string instrstring = instruction_identification(i);
1705  int so = statement_ordering(s);
1706  entity called = entity_undefined;
1707 
1708  if(same_string_p(instrstring, "CALL")) {
1709  called = call_function(instruction_call(i));
1710  }
1711 
1712  int n = asprintf(&buffer, "%td (%d, %d) at %p: %s %s\n",
1713  statement_number(s),
1714  ORDERING_NUMBER(so),
1715  ORDERING_STATEMENT(so),
1716  s,
1717  instrstring,
1718  entity_undefined_p(called)? "" : module_local_name(called));
1719 
1720  pips_assert("asprintf ok", n!=-1);
1721 
1722  return buffer;
1723 }
1724 
1725 string
1727 {
1728  if(statement_undefined_p(s)) {
1729  return "undefined statement\n";
1730  }
1732  return "statement with undefined intruction\n";
1733  }
1734  else
1735  return statement_identification(s);
1736 }
1737 
1738 
1739 static bool
1741 {
1742  string the_comments = statement_comments(s);
1743  if (!empty_comments_p(the_comments)) {
1744  string old = *all_comments;
1745  *all_comments = strdup(
1746  old==NULL?
1747  the_comments:
1748  concatenate(old, the_comments, NULL));
1749  free(old);
1750  }
1751  return true;
1752 }
1753 
1754 
1755 /* Gather all the comments recursively found in the given statement
1756  and return them in a strduped string (NULL if no comment found).
1757 
1758  Do not forget to free the string returned later when no longer
1759  used. */
1761 {
1762  string comments = NULL;
1763  gen_context_recurse(s, &comments, statement_domain,
1765  return comments?comments:empty_comments;
1766 }
1767 
1768 
1769 /* Find the first non-empty comment of a statement, if any
1770  * returns a pointer to the comment if found,
1771  * pointer to a "string_undefined" otherwise */
1773 {
1774  static char * an_empty_comment = empty_comments;
1775  if (statement_block_p(s)) {
1778  if (!empty_comments_p(*comment))
1779  /* We've found it! */
1780  return comment;
1781  }
1782  /* No comment found: */
1783  return &an_empty_comment;
1784  }
1785  else
1786  /* Ok, plain statement: */
1787  return &statement_comments(s);
1788 }
1789 
1790 /* Find the first comment of a statement, if any.
1791  * returns a pointer to the comment if found, NULL otherwise
1792  *
1793  * Unfortunately empty_comments may be used to decorate a statement
1794  * although this makes the statement !gen_defined_p(). empty_comments
1795  * is also used as a return value to signal that non statement
1796  * legally carrying a comment has been found.
1797  *
1798  * The whole comment business should be cleaned up.
1799  */
1800 static
1802 {
1803  static char * an_empty_comment = empty_comments;
1804  if (statement_block_p(s)) {
1807  /* let's hope the parser generates an empty string as
1808  comment rather than empty_comments which is defined as
1809  empty_string */
1810  if (*comment!=empty_comments)
1811  /* We've found it! */
1812  return comment;
1813  }
1814  /* No comment found: */
1815  return &an_empty_comment;
1816  }
1817  else
1818  /* comment carrying statement: */
1819  return &statement_comments(s);
1820 }
1821 
1822 
1823 /* Put a comment on a statement in a safe way. That is it find the
1824  first non-block statement to attach it or insert a CONTINUE and put
1825  the statement on it. You should free the old one...
1826 
1827  The comment should have been malloc()'ed before.
1828 
1829  Return true on success, false else. */
1830 bool
1832  string the_comments)
1833 {
1835  if (instruction_sequence_p(i)) {
1836  /* We are not allowed to put a comment on a sequence, find the
1837  first non sequence statement if any: */
1838  MAP(STATEMENT, st,
1839  {
1840  if (try_to_put_a_comment_on_a_statement(st, the_comments))
1841  /* Ok, we succeed to put the comment: */
1842  return true;
1843  },
1845  /* Hmm, no good statement found to attach a comment: */
1846  return false;
1847  }
1848  else {
1849  /* Ok, it is a plain statement, we can put a comment on it: */
1850  statement_comments(s) = the_comments;
1851  return true;
1852  }
1853 }
1854 
1855 
1856 /* Similar to try_to_put_a_comment_on_a_statement() but insert a
1857  CONTINUE to put the comment on it if there is only empty
1858  sequence(s)
1859 
1860  The comment should have been malloc()'ed before.
1861 */
1862 void
1864  string the_comments)
1865 {
1866  if (empty_comments_p(the_comments))
1867  /* Nothing to add... */
1868  return;
1869 
1870  if (!try_to_put_a_comment_on_a_statement(s, the_comments)) {
1871  /* It failed because it is an empty sequence. So add a
1872  CONTINUE to attach the statement on it: */
1875  statement_comments(s_cont) = the_comments;
1877  s_cont,
1878  sequence_statements(seq));
1879  }
1880 }
1881 
1882 
1883 /* Append a comment string (if non empty) to the comments of a
1884  statement, if the c.
1885 
1886  @param the_comments is strdup'ed in this function.
1887 */
1888 void
1890  string the_comments)
1891 {
1892 
1893 
1894  if (empty_comments_p(the_comments))
1895  /* Nothing to add... */
1896  return;
1897 
1898  char **old = find_first_statement_comment(s);
1899  if (empty_comments_p(*old))
1900  /* There is no comment yet: */
1901  put_a_comment_on_a_statement(s, strdup(the_comments));
1902  else {
1903  char * new = strdup(concatenate(*old, the_comments, NULL));
1904  free(*old);
1905  *old=empty_comments;
1907  }
1908 }
1909 
1910 
1911 /* Insert a comment string (if non empty) at the beginning of the
1912  comments of a statement.
1913 
1914  @param the_comments is strdup'ed in this function.
1915 */
1917  const char* the_comments) {
1918  if (empty_comments_p(the_comments))
1919  /* Nothing to add... */
1920  return;
1921 
1922  char **old = find_first_comment(s);
1923  if ( empty_comments_p(*old) ) {
1924  /* There are no comments yet: */
1925  put_a_comment_on_a_statement(s, strdup(the_comments));
1926  } else {
1927  char * new = strdup(concatenate(the_comments, *old, NULL));
1928  free(*old);
1929  *old=empty_comments;
1931  }
1932 }
1933 
1934 
1935 /* as name indicate, a comment is added.
1936  */
1937 #define ERROR_PREFIX "!ERROR: "
1938 #define BUFSIZE 1024
1939 
1940 void add_one_line_of_comment(statement s, string format, ...)
1941 {
1942  char buffer[BUFSIZE];
1943  int error;
1944  va_list some_arguments;
1945 
1946  va_start(some_arguments, format);
1947  error = vsnprintf(buffer, BUFSIZE, format, some_arguments);
1948  if (error<0) {
1949  pips_internal_error("buffer too small");
1950  }
1951  va_end(some_arguments);
1952 
1953  if (s)
1954  {
1956  {
1958  }
1959  else
1960  {
1961  string newcom =
1964  statement_comments(s) = newcom;
1965  }
1966  }
1967  else
1968  {
1969  fprintf(stderr, ERROR_PREFIX "%s\n", buffer);
1970  }
1971 }
1972 
1973 
1974 /* Since block cannot carry comments nor line numbers, they must be
1975  moved to an internal continue statement.
1976 
1977  A prettier version could be to make a new block containing the
1978  continue and then the old block. Comments might be better located.
1979  */
1981 {
1982  string osc = statement_comments(s);
1983  statement ns = s;
1984 
1985  if(osc!=NULL && !string_undefined_p(osc)) {
1986  free(osc);
1987  }
1988 
1989  if(!statement_block_p(s)) {
1990  statement_comments(s) = sc;
1991  statement_number(s) = sn;
1992  }
1993  else if(!string_undefined_p(sc)) {
1994  /* A continue statement must be inserted as first block statement*/
1997  statement_comments(nops) = sc;
1998  statement_number(nops) = sn;
2000  CONS(STATEMENT, nops, sss);
2001  }
2002  return ns;
2003 }
2004 
2005 
2006 /* Since blocks are not represented in Fortran, they cannot
2007  * carry a label. A continue could be added by the prettyprinter
2008  * but it was decided not to support this facility.
2009  * For debugging, it's better to have a transparent prettyprinter
2010  * and no ghost statement with no ordering and no number.
2011  *
2012  * Insert a CONTINUE and move the label, comment and statement number
2013  * if any from the statement to the CONTINUE, if label there is.
2014  */
2015 void
2017 {
2018  pips_assert("Should be an instruction block...",
2020 
2022  /* The statement block has no label and no comment: just do
2023  nothing. */
2025  }
2026  else {
2027  /* FI: why don't you try to keep them on the first statement,
2028  just in case it has empty slots? */
2029  /* There are some informations we need to keep: just add a
2030  CONTINUE to keep them: */
2031  list instructions;
2032  statement continue_s;
2033  const char* label_name =
2035 
2036  instructions = instruction_block(statement_instruction(s));
2037 
2038  if (strcmp(label_name, RETURN_LABEL_NAME) == 0)
2039  /* This the label of a RETURN, do not forward it: */
2041  else
2042  continue_s = make_continue_statement(statement_label(s));
2043 
2045  statement_comments(continue_s) = statement_comments(s);
2047  statement_number(continue_s) = statement_number(s);
2049 
2050  /* FI: at least in for loop to while loop conversion, the
2051  extensions is moved down to the while loop. I'm not sure
2052  this is the best source code location to fix the
2053  problem. I do not know if the extensions have been reused
2054  directly and so do not need to be freed here or not. In
2055  fact, it is copied below and could be freed. */
2056  // FI: This leads to an inconsistency in gen_recurse() when the
2057  // while loop is reached, but only when the new_controlizer is
2058  // used; I cannot spend more time on this right now
2059  // See: transform_a_for_loop_into_a_while_loop(). it might be
2060  // safer to operate at the statement level with a test for
2061  // forloop statements rather than use ancestors
2063  free_extensions(ext);
2065 
2066  instructions = CONS(STATEMENT, continue_s, instructions);
2067  instruction_block(statement_instruction(s)) = instructions;
2068 
2069  //pips_assert("The transformed statement s is consistent",
2070  // statement_consistent_p(s));
2071  }
2072 }
2073 
2074 
2075 /* Apply fix_sequence_statement_attributes() on the statement only if
2076  it really a sequence. */
2077 void
2079 {
2081  if (!instruction_undefined_p(i)) {
2082  if (instruction_sequence_p(i))
2084  }
2085 }
2086 
2087 
2088 /* See if statement s is labelled and can be reached by a GO TO */
2089 entity
2091 {
2092  entity l = statement_label(s);
2093 
2094  if(format_statement_p(s)) {
2095  /* You cannot jump onto a non-executable statement */
2096  l = entity_empty_label();
2097  }
2098  else if(entity_empty_label_p(l)) {
2100 
2101  switch(instruction_tag(i)) {
2102 
2104  /* The initial statement may be an unlabelled CONTINUE... */
2105  MAPL(cs, {
2106  statement stmt = STATEMENT(CAR(cs));
2107  l = statement_to_label(stmt);
2109  break;
2111  break;
2114  break;
2115  case is_instruction_call:
2116  case is_instruction_test:
2117  case is_instruction_loop:
2119  case is_instruction_goto:
2122  break;
2123  default:
2124  pips_internal_error("Ill. tag %d for instruction",
2125  instruction_tag(i));
2126  }
2127  }
2128 
2129  debug(8, "statement_to_label", "stmt %s, pointed by = %s\n",
2131 
2132  return l;
2133 }
2134 
2135 
2136 /* Add a label to a statement. If the statement cannot accept a label (it
2137  is a sequence or it has already a label...), add a CONTINUE in front of
2138  the statement to carry it.
2139 
2140  @return \param s with the new \param label if it was possible to add it
2141  directly, or a new statement sequence with the new \param label added
2142  to a CONTINUE followed by the old statement \param s.
2143 
2144  \param label is the label to add to the statement
2145 
2146  \param s is the statement to be labelled
2147 
2148  \param labeled_statement is a pointer to a statement. It is initialized
2149  by the function to the statement that really get the label on. It is
2150  useful when we need to track it, for exemple for "goto" generation in
2151  the parser.
2152 
2153  The caller is responsible to *avoid* garbage collecting on \param s if a
2154  new statements are allocated in this fonction since it is included in
2155  the return statement.
2156  */
2157 statement
2159  statement s,
2160  statement *labeled_statement) {
2161  /* Test with statement_to_label to deal with a label inside an
2162  instruction block: */
2163  entity old_label = statement_to_label(s);
2164  if (old_label == entity_undefined
2166  && unlabelled_statement_p(s))) {
2167  statement_label(s) = label;
2168  *labeled_statement = s;
2169  return s;
2170  }
2171  else {
2172  /* Add a continue as a label landing pad since a statement can not
2173  have more than 1 label and a sequence cannot have a label: */
2175  *labeled_statement = c;
2176  list stmts = gen_statement_cons(s, NIL);
2177  stmts = gen_statement_cons(c, stmts);
2178  statement seq = make_block_statement(stmts);
2179  return seq;
2180  }
2181 }
2182 
2183 
2184 /* Returns false is no syntactic control path exits s (i.e. even if true is returned
2185  * there might be no control path). Subroutines and
2186  * functions are assumed to always return to keep the analysis intraprocedural.
2187  * See the continuation library for more advanced precondition-based analyses.
2188  *
2189  * true is a safe default value.
2190  *
2191  * The function name is misleading: a RETURN statement does not return...
2192  * It should be called "statement_does_continue()"
2193  */
2194 bool
2196 {
2197  bool returns = true;
2199  test t = test_undefined;
2200 
2201  switch(instruction_tag(i)) {
2203  MAPL(sts,
2204  {
2205  statement st = STATEMENT(CAR(sts)) ;
2206  if (!statement_does_return(st)) {
2207  returns = false;
2208  break;
2209  }
2210  },
2212 
2213  break;
2216  break;
2217  case is_instruction_call:
2218  /* the third condition is due to a bug/feature of unspaghettify */
2219  returns = !stop_statement_p(s) && !return_statement_p(s) &&
2221  break;
2222  case is_instruction_test:
2223  t = instruction_test(i);
2224  returns = statement_does_return(test_true(t)) ||
2226  break;
2227  case is_instruction_loop:
2229  /* No precise answer, unless you can prove the loop executes at
2230  * least one iteration.
2231  */
2232  returns = true;
2233  break;
2234  case is_instruction_goto:
2235  /* returns = statement_does_return(instruction_goto(i)); */
2236  returns = false;
2237  break;
2239  break;
2241  break;
2242  default:
2243  pips_internal_error("Ill. tag %d for instruction",
2244  instruction_tag(i));
2245  }
2246 
2247  debug(8, "statement_does_return", "stmt %s, does return= %d\n",
2248  statement_identification(s), returns);
2249 
2250  return returns;
2251 }
2252 
2253 bool
2255 {
2256  bool returns = false;
2257  control entry = unstructured_control(u);
2259  list nodes = NIL;
2260 
2261  FORWARD_CONTROL_MAP(c, {
2262  returns = returns || (c==exit);
2263  }, entry, nodes);
2264  gen_free_list(nodes);
2265 
2266  return returns;
2267 }
2268 
2269 void
2271 {
2273  if (instruction_format_p(i)) {
2274  /* Put the instruction with the statement attributes in
2275  new_format. */
2276  statement new_format = instruction_to_statement(i);
2277  statement_label(new_format) = statement_label(s);
2278  statement_number(new_format) = statement_number(s);
2279  statement_comments(new_format) = statement_comments(s);
2280  statement_extensions(new_format) = statement_extensions(s);
2281  /* Replace the old FORMAT with a NOP: */
2288 
2289  *all_formats = CONS(STATEMENT, new_format,*all_formats);
2290  }
2291 }
2292 
2293 
2294 /* Used to keep aside the FORMAT before many code transformation that
2295  could remove them either. It just return a list of all the FORMAT
2296  statement and replace them with NOP. */
2297 list
2299 {
2300  list all_formats = NIL;
2301 
2302  gen_context_recurse(s,&all_formats, statement_domain,
2304 
2305  return all_formats = gen_nreverse(all_formats);
2306 }
2307 
2308 
2309 /* Transfer all the FORMATs at the very beginning of a module: */
2310 void
2312 {
2313  /* Pick up all the FORMATs of the module: */
2315  ifdebug (1)
2316  pips_assert("Incorrect statements...", statement_consistent_p(s));
2317  /* And put them at the very beginning of the module: */
2318  formats=gen_nreverse(formats);
2319  FOREACH(STATEMENT,f,formats)
2320  insert_statement(s,f,true);
2321  ifdebug (1)
2322  pips_assert("Incorrect statements...", statement_consistent_p(s));
2323 }
2324 
2325 
2326 /* Transfer all the FORMATs at the very end of a module: */
2327 void
2329 {
2330  /* Pick up all the FORMATs of the module: */
2332  ifdebug (1)
2333  pips_assert("Incorrect statements...", statement_consistent_p(s));
2334  /* And put them at the very beginning of the module: */
2335  FOREACH(STATEMENT,f,formats)
2336  insert_statement(s,f,false);
2337  ifdebug (1)
2338  pips_assert("Incorrect statements...", statement_consistent_p(s));
2339 }
2340 
2341 
2342 bool
2343 figure_out_if_it_is_a_format(instruction i, bool *format_inside_statement_has_been_found)
2344 {
2345  if (instruction_format_p(i)) {
2346  *format_inside_statement_has_been_found = true;
2347  /* Useless to go on further: */
2348  gen_recurse_stop(NULL);
2349  return false;
2350  }
2351  return true;
2352 }
2353 
2354 
2355 /* Return true only if there is a FORMAT inside the statement:
2356 
2357  @addtogroup statement_predicate
2358 */
2359 bool
2361 {
2362  bool format_inside_statement_has_been_found = false;
2363 
2364  gen_context_recurse(s,&format_inside_statement_has_been_found,
2366 
2367  return format_inside_statement_has_been_found;
2368 }
2369 
2370 
2371 /* Number of comment line *directly* attached to a statement.
2372  * Should be zero for sequences.
2373  */
2374 int
2376 {
2377  int length = 0;
2378  string cmt = statement_comments(stmt);
2379 
2380  if(string_undefined_p(cmt)) {
2381  /* Is it allowed? Should be the empty string... */
2382  length = 0;
2383  }
2384  else {
2385  char c;
2386  while((c=*cmt++)!= '\0')
2387  if(c=='\n')
2388  length++;
2389  }
2390 
2391  return length;
2392 }
2393 
2394 ␌
2395 /* Poor attempt at associating physical line numbers to statement.
2396  *
2397  * Lines used for declarations are counted elsewhere: see
2398  * module_to_declaration_length()
2399  *
2400  * It is assumed that each statement fits on one physical line,
2401  * excepts sequences which require 0 line. Non statement such as
2402  * ENDIF, ELSE, ENDDO,... must be taken care of too.
2403  */
2404 
2405 static int current_line = -1;
2407 
2408 static bool
2410 {
2412 
2414 
2415  /* Is it printable on one line? */
2416  if(instruction_sequence_p(i)) {
2417  current_line += 0;
2418  }
2420  /* Must be an unlabelled CONTINUE */
2421  current_line += 0;
2422  }
2423  else {
2424  current_line += 1;
2425  }
2426 
2428 
2429  return true;
2430 }
2431 
2432 static void
2434 {
2436 
2437  if(instruction_loop_p(i)) {
2438  loop l = instruction_loop(i);
2439 
2441  /* There must be an ENDDO here */
2442  current_line += 1;
2443  }
2444  }
2445  else if(instruction_test_p(i)
2447  /* There must be an ENDIF here */
2448  /* I doubt it's a real good way to detect synthetic IFs */
2449  current_line += 1;
2450  }
2451  /* What could be done for ELSE and ELSEIF? */
2452  /* An else stack should be built. Use
2453  * DEFINE_LOCAL_STACK(name, type)
2454  * DEFINE_LOCAL_STACK(else_stack, statement)
2455  * Note that it should be pushed and poped in the down_counter() function
2456  */
2457 }
2458 
2461 {
2463 
2465 
2466  current_line = 0;
2467 
2469 
2470  s_to_l = stmt_to_line;
2472  return s_to_l;
2473 }
2474 
2475 /* insert statement s1 before or after statement s
2476  *
2477  * If statement s is a sequence, simply insert s1 at the beginning
2478  * or at the end of the sequence s.
2479  *
2480  * If not, create a new statement s2 with s's fields and update
2481  * s as a sequence with no comments and undefined number and ordering.
2482  * The sequence is either "s1;s2" if "before" is true or "s2;s1" else.
2483  *
2484  *
2485  * ATTENTION !!! : this version is not for unstructured case and this
2486  * is not asserted.
2487  *
2488  * s cannot be a declaration statement, because the insertion scheme
2489  * used would modify its scope. Also s1 cannot be a declaration if s
2490  * is not a sequence. And if s is a sequence
2491  * add_declaration_statement() should be used instead to insert the
2492  * new declaration at the best possible place.
2493  */
2495  statement s1,
2496  bool before)
2497 {
2498  list ls;
2500  if (instruction_sequence_p(i))
2501  {
2502  ls = instruction_block(i);
2503  if (before)
2504  {
2505  if(!ENDP(ls) && declaration_statement_p(STATEMENT(CAR(ls))))
2506  {
2507  while( !ENDP(CDR(ls)) && declaration_statement_p(STATEMENT(CAR(CDR(ls))))) POP(ls);
2508  CDR(ls)=CONS(STATEMENT,s1,CDR(ls));
2509  ls=instruction_block(i);
2510  }
2511  else
2512  ls = CONS(STATEMENT,s1,ls);
2513  }
2514  else
2515  ls = gen_nconc(ls,CONS(STATEMENT,s1,NIL));
2516  instruction_block(i) = ls;
2517  }
2518  else
2519  {
2521  statement_label(s),
2522  statement_number(s),
2523  statement_ordering(s),
2524  statement_comments(s),
2529  );
2530  /* no duplication */
2537  statement_decls_text(s)=NULL;
2539 
2540  if (before)
2541  ls = CONS(STATEMENT,s1,CONS(STATEMENT,s2,NIL));
2542  else
2543  ls = CONS(STATEMENT,s2,CONS(STATEMENT,s1,NIL));
2544 
2546  }
2547 }
2548 
2549 /* This is the normal entry point. See previous function for comments.
2550  *
2551  * insert statement s1 before or after statement s
2552  *
2553  * If statement s is a sequence, simply insert s1 at the beginning
2554  * or at the end of the sequence s.
2555  *
2556  * If not, create a new statement s2 with s's fields and update
2557  * s as a sequence with no comments and undefined number and ordering.
2558  * The sequence is either "s1;s2" if "before" is true or "s2;s1" else.
2559  *
2560  *
2561  * ATTENTION !!! : this version is not for unstructured case and this
2562  * is not asserted.
2563  *
2564  * s cannot be a declaration statement, because the insertion scheme
2565  * used would modify its scope. Also s1 cannot be a declaration if s
2566  * is not a sequence. And if s is a sequence
2567  * add_declaration_statement() should be used instead to insert the
2568  * new declaration at the best possible place.
2569  */
2571 {
2572  pips_assert("Neither s nor s1 are declaration statements",
2575  generic_insert_statement(s, s1, before);
2576 }
2577 
2578 /* Break the IR consistency or, at the very least, do not insert new
2579  declarations at the usual place, i.e. at the end of the already
2580  existing declarations. */
2582 {
2583  generic_insert_statement(s, s1, before);
2584 }
2585 
2587 {
2588  pips_assert("b is a block statement", statement_block_p(b));
2589  list sl = statement_block(b);
2591  gen_nconc(sl, CONS(STATEMENT, s, NIL));
2592 }
2593 
2594 // there should be a space at the beginning of the string
2595 #define PIPS_DECLARATION_COMMENT "PIPS generated variable\n"
2596 static string
2598 {
2600 }
2601 
2602 // hmmm... why not use the "stack" type, instead of betting?
2603 #define MAX_COMMENTERS 8
2604 
2605 /* commenters are function used to add comments to pips-created variables
2606  * they are handled as a limited size stack
2607  * all commenters are supposed to return allocated data
2608  */
2612  [0]=default_generated_variable_commenter /* c99 inside :) */
2613 };
2614 static size_t nb_commenters=1;
2615 
2617 {
2618  pips_assert("not exceeding stack commenters stack limited size\n",
2621 }
2622 
2624 {
2625  pips_assert("not removing default commenter",nb_commenters!=1);
2626  --nb_commenters;
2627 }
2628 
2630 {
2632 }
2633 ␌
2634 /* Check if declaration of variable nv can be added to the declaration
2635  * list of statement s.
2636  *
2637  * This is considered legal if:
2638  *
2639  * - the comments match;
2640  *
2641  * - the basic of the types of nv and a variable already declared in
2642  * s, fv, are equal;
2643  *
2644  * - the qualifiers of nv and fv are equal
2645  *
2646  * - the storage are equal if ram storage are used for both fv and nv
2647  *
2648  * This function impacts the layout of the declarations and hence the
2649  * prettyprint. Any modification is likely to disturb the validation.
2650  *
2651  * This function is not safe. Statement s must be a declaration
2652  * statement with a non-empty declaration list.
2653  *
2654  * The code could be shortened by using a big logical expression, but
2655  * this would not improve readability or debugability.
2656  */
2658  string c,
2659  entity nv)
2660 {
2661  bool add_p = false;
2662  if (statement_declarations(s) == NIL) {
2663  return add_p;
2664  }
2666  bool comment_p = comments_equal_p(statement_comments(s),c);
2667  bool basic_p = false;
2669  && !basic_undefined_p(entity_basic(fv))) {
2670  basic_p = basic_equal_p(entity_basic(nv),entity_basic(fv));
2671  }
2672  bool qualifiers_p =
2674  bool storage_p =
2677  ==ram_section(storage_ram(entity_storage(nv)))):false)
2678  :true;
2679 
2680  add_p = comment_p && basic_p && qualifiers_p && storage_p;
2681 
2682  return add_p;
2683 }
2684 
2685 /* Add a new declaration statement
2686  *
2687  * Declarations are not only lists of entities at the block level and
2688  * in the symbol table, but also declaration statement to
2689  * carry the line number, comments, and the declarations local to the
2690  * declaration statement. This function is low-level and does not
2691  * maintain the consistency of the PIPS internal representation.
2692  *
2693  * @param s Statement s must be a sequence. A new declaration statement is
2694  * generated to declare e. This statement is inserted after the
2695  * existing declaration statements in s, or, if no declaration statement
2696  * is present, at the beginning of the sequence in s.
2697  *
2698  * @param e Variable to declare.
2699  * The declaration of e at s level is not checked. The existence of a
2700  * previous declaration statement for e is not checked either. The
2701  * caller is responsible for the consistency management between the
2702  * declaration statements in s and the list of declaration at s level.
2703  *
2704  * @return statement s modified by side-effects.
2705  *
2706  * For the time being, a declaration statement is a continue
2707  * statement.
2708  * Beware that the possible dependencies between the new declaration
2709  * and existing declarations are not checked.
2710  */
2712 {
2713  if(statement_block_p(s)) {
2714  list sl = statement_block(s); //statement list
2715  list cl = list_undefined; // current statement list
2716  list pl = NIL; // previous statement list
2717  list nsl = list_undefined; // new statement list
2718  string comment = generated_variable_comment(e);
2721  comment);
2722 
2723  if (before_p)
2724  cl = sl;
2725  else
2726  {
2727  /* Look for the last declaration: it is pointed to by pl */
2728  for(cl=sl; !ENDP(cl); POP(cl)) {
2729  statement cs = STATEMENT(CAR(cl));
2730  if(declaration_statement_p(cs)) {
2731  pl = cl;
2732  }
2733  else {
2734  break;
2735  }
2736  }
2737  }
2738 
2739  /* Do we have previous declarations to skip? */
2740  if(!ENDP(pl)) {
2741  /* SG: if CAR(pl) has same comment and same type as ds, merge them */
2742  statement spl = STATEMENT(CAR(pl));
2744  free_statement(ds);
2746  nsl=sl;
2747  }
2748  /* SG: otherwise, insert ds */
2749  else
2750  {
2751  CDR(pl) = NIL; // Truncate sl
2752  nsl = gen_nconc(sl, CONS(STATEMENT, ds, cl));
2753  }
2754  }
2755  else { // pl == NIL
2756  /* The new declaration is inserted before sl*/
2757  pips_assert("The above loop was entered at most once", sl==cl);
2758  if (before_p && !ENDP(sl) && declaration_statement_p(STATEMENT(CAR(sl))))
2759  {
2760  statement ssl = STATEMENT(CAR(sl));
2762  {
2763  free_statement(ds);
2765  nsl=sl;
2766  }
2767  else
2768  nsl = CONS(STATEMENT, ds, sl);
2769  }
2770  else
2771  nsl = CONS(STATEMENT, ds, sl);
2772  }
2773 
2775  }
2776  else
2777  {
2778  pips_internal_error("can only add declarations to statement blocks");
2779  }
2780 
2781  // FI: avoid the ri/prettyprint cycle
2782  /* ifdebug(8) { */
2783  /* pips_debug(8, "Statement after declaration insertion:\n"); */
2784  /* print_statement(s); */
2785  /* } */
2786 
2787  return s;
2788 }
2789 
2791 {
2792  return generic_add_declaration_statement(s, e, false);
2793 }
2794 
2796 {
2797  return generic_add_declaration_statement(s, e, true);
2798 }
2799 
2800 /**
2801  * Add a new declaration statement
2802  * (inspired by generic_add_declaration_statement)
2803  *
2804  * A new declaration statement is generated to declare e.
2805  * This statement is inserted before or after the
2806  * statements s in statement block_statement.
2807  * s must be a statement directly (no recursively) present
2808  * in statement block_statement
2809  *
2810  * Declarations are not only lists of entities at the block level and
2811  * in the symbol table, but also declaration statement to
2812  * carry the line number, comments, and the declarations local to the
2813  * declaration statement. This function is low-level and does not
2814  * maintain the consistency of the PIPS internal representation.
2815  *
2816  * \param block_statement must be a sequence that contain statement s
2817  * strictly the same pointer than s and not a copy.
2818  *
2819  * \param s Statement after or before which declaration is inserted
2820  *
2821  * \param e Variable to declare.
2822  * The declaration of e at block_statement level is not checked.
2823  * The existence of a previous declaration statement for e is not checked either.
2824  * The caller is responsible for the consistency management between the
2825  * declaration statements in block_statement and the list of declaration
2826  * at block_statement level.
2827  *
2828  * \param before_p declaration add before s if before_p==true
2829  *
2830  * \return statement declaration generated or modified
2831  * statement_undefined if the add fail
2832  *
2833  * For the time being, a declaration statement is a continue
2834  * statement.
2835  * Beware that the possible dependencies between the new declaration
2836  * and existing declarations are not checked.
2837  * WARNING : block_statement is modify by side effect
2838  */
2840 {
2842  if(statement_block_p(block_statement)) {
2843  list sl = statement_block(block_statement); //statement list
2844  list cl = list_undefined; // current statement list
2845  list pl = NIL; // previous statement list
2846  list nsl = list_undefined; // new statement list
2847  string comment = generated_variable_comment(e);
2850  comment);
2851 
2852  bool find = false;
2853  /* Look for the statement s: it is pointed to by pl */
2854  for(cl=sl; !ENDP(cl) && !find; POP(cl)) {
2855  statement cs = STATEMENT(CAR(cl));
2856  // if ( statement_number(cs) == statement_number(s)
2857  // && statement_ordering(cs) == statement_ordering(s) )
2858  if (cs == s)
2859  {
2860  find = true;
2861  if (!before_p) {
2862  POP(cl);
2863  pl = cl;
2864  }
2865  break;
2866  }
2867  pl = cl;
2868  }
2869  if (!find) {
2870  pips_internal_error("statement s:%p (%d) must be in block block_statement:%p (%d) (not recursively but directly)\n",
2871  s, statement_number(s), block_statement, statement_number(block_statement));
2872  }
2873 
2874  /* Do we have previous declarations to skip? */
2875  if(!ENDP(pl)) {
2876  /* SG: if CAR(pl) has same comment and same type as ds, merge them */
2877  statement spl = STATEMENT(CAR(pl));
2879  free_statement(ds);
2880  ds = spl;
2882  nsl=sl;
2883  }
2884  /* SG: otherwise, insert ds */
2885  else {
2886  CDR(pl) = NIL; // Truncate sl
2887  nsl = gen_nconc(sl, CONS(STATEMENT, ds, cl));
2888  }
2889  }
2890  else { // pl == NIL
2891  /* The new declaration is inserted before sl*/
2892  pips_assert("The above loop was entered at most once", sl==cl);
2893  if (before_p && !ENDP(sl) && declaration_statement_p(STATEMENT(CAR(sl)))) {
2894  statement ssl = STATEMENT(CAR(sl));
2896  free_statement(ds);
2897  ds = ssl;
2899  nsl=sl;
2900  }
2901  else
2902  nsl = CONS(STATEMENT, ds, sl);
2903  }
2904  else
2905  nsl = CONS(STATEMENT, ds, sl);
2906  }
2907 
2908  instruction_block(statement_instruction(block_statement)) = nsl;
2909  }
2910  else {
2911  pips_internal_error("can only add declarations to statement blocks");
2912  }
2913 
2914  // FI: avoid the ri/prettyprint cycle
2915  /* ifdebug(8) { */
2916  /* pips_debug(8, "Statement after declaration insertion:\n"); */
2917  /* print_statement(block_statement); */
2918  /* } */
2919 
2920  return ds;
2921 }
2922 
2923 /* s is assumed to be a block statement and its declarations field is
2924  assumed to be correct, but not necessarily the declaration
2925  statements within the block s. This function checks that no variable is
2926  declared by a declaration statement within the block but not
2927  declared at the block level. Also, if a variable is declared at the
2928  block level but not by a declaration statement, a new declaration
2929  statement is added. */
2931 {
2932  list bdvl = gen_copy_seq(statement_declarations(s)); // block declarations
2933 
2934  pips_assert("s is a block statement", statement_block_p(s));
2935  pips_assert("No multiple declarations in declarations of s", gen_once_p(bdvl));
2936 
2937  if(!ENDP(bdvl)) {
2938  list sl = statement_block(s);
2939  list edvl = statements_to_direct_declarations(sl); // effective declarations
2940  list mdvl = gen_copy_seq(statement_declarations(s)); // block declarations
2941 
2942  // List of variables declared within the block but not at the
2943  // block level
2944  gen_list_and_not(&mdvl, edvl); // missing declarations
2945 
2946  // Add the missing declaration statements.
2947  // Might be better to add only one statement for all missing variables...
2948  FOREACH(ENTITY, v, mdvl) {
2950  }
2951  gen_free_list(mdvl);
2952 
2953  // List of variables declared within the block but not at the
2954  // block level
2955  gen_list_and_not(&edvl, bdvl);
2956 
2957  pips_assert("edvl-bdvl=empty set", ENDP(edvl));
2958  gen_free_list(edvl);
2959  }
2960  gen_free_list(bdvl);
2961 }
2962 
2963 /* Declarations are not only lists of entities, but also statement to
2964  carry the line number, comments,... For the time begin, a
2965  declaration statement is a continue statement. */
2967 {
2968  if(statement_block_p(s)) {
2969  list sl = statement_block(s); //statement list
2970  list cl = list_undefined; // current statement list
2971 
2972  /* Look for the last declaration: it is pointed to by pl */
2973  for(cl=sl; !ENDP(cl); POP(cl)) {
2974  statement cs = STATEMENT(CAR(cl));
2975  if(declaration_statement_p(cs)) {
2976  // We don't use FOREACH because we aim to delete an element while iterating
2977  list prev=NULL;
2979  !ENDP(current);
2980  POP(current)) {
2981  if(e == ENTITY(CAR(current))) {
2982  pips_debug(0,"Removing %s\n",entity_name(e));
2983  // For replacing it, we have first to remove the old one from the list
2984  if(prev == NULL) {
2986  } else {
2987  CDR(prev) = CDR(current);
2988  }
2989  free(current);
2990  break;
2991  }
2992  prev=current; // Save current iterator, because we might remove the next one
2993  }
2994  }
2995  }
2996  }
2997  else
2998  {
2999  pips_internal_error("can only add declarations to statement blocks");
3000  }
3001 
3002  // FI: to avoid a cycle between the ri-util and prettyprint libraries
3003  /* ifdebug(8) { */
3004  /* pips_debug(8, "Statement after declaration insertion:\n"); */
3005  /* print_statement(s); */
3006  /* } */
3007 
3008  return s;
3009 }
3010 
3011 /* Replace the instruction in statement s by instruction i.
3012  *
3013  * Free the old instruction.
3014  *
3015  * If the new instruction is a sequence,
3016  * add a CONTINUE to carry the label and/or the comments. The
3017  * statement number and ordering are set to undefined.
3018  *
3019  * Else if the new instruction is not a sequence, the statement number
3020  * and the ordering are also set to undefined because the connexion
3021  * with the parsed line is lost and the ordering most likely obsolete.
3022  * If the parsed statement number is still meaningfull, the caller must
3023  * take care of it.
3024  *
3025  * If the initial instruction has been re-used, do not forget
3026  * to dereference it before calling this function:
3027  *
3028  * statement_instruction(s) = instruction_undefined;
3029  *
3030  * Be careful with the label and the comments too: they may have
3031  * been reused.
3032  *
3033  *
3034  * ATTENTION !!! : this version is not for unstructured case
3035  *
3036  *
3037  */
3038 
3040 {
3041  /* reset numbering and ordering */
3044 
3045  /* try hard to keep comments and label when relevant */
3046  if (instruction_sequence_p(i) && (
3048  (!unlabelled_statement_p(s) && !entity_return_label_p(statement_label(s))) /*SG:note the special return-label case */
3049  ) )
3050  {
3055 
3056  /* add the CONTINUE statement before the sequence instruction i */
3058 
3061  }
3062 
3063  else
3064  {
3066  statement_instruction(s) = i;
3067  /* SG: if the old statement had declarations, they are removed
3068  * maybe we should regenerate the new one if any to keep global coherency ?*/
3075  }
3076  return s;
3077 }
3078 
3079 /* Assume that statement rs appears in statement as and replaced it
3080  by a statement list. */
3082 {
3083  // FI: to avoid a cycle between the ri-util and prettyprint libraries
3084  /* ifdebug(8) { */
3085  /* pips_debug(8, "Ancestor statement before substitution:\n"); */
3086  /* print_statement(as); */
3087  /* } */
3088  if(statement_block_p(as)) {
3089  list asl = statement_block(as);
3091  if(asl==NULL) {
3092  pips_internal_error("The statement is not part of its ancestor");
3093  }
3094  gen_substitute_chunk_by_list(&asl, (void *) rs, sl);
3095  instruction_block(asi) = asl;
3096  }
3097  else {
3098  pips_internal_error("not implemented yet");
3099  }
3100  // FI: to avoid a cycle between the ri-util and prettyprint libraries
3101  /* ifdebug(8) { */
3102  /* pips_debug(8, "Ancestor statement after substitution:\n"); */
3103  /* print_statement(as); */
3104  /* } */
3105 }
3106 ␌
3107 static bool find_implicit_goto(statement s, list * tl)
3108 {
3109  bool found = false;
3110 
3111  if(statement_call_p(s)) {
3113  entity f = call_function(c);
3114 
3116  list ce = list_undefined;
3117 
3118  for(ce = call_arguments(c); !ENDP(ce); ce = CDR(CDR(ce))) {
3119  expression e = EXPRESSION(CAR(ce));
3121 
3122  pips_assert("expression e must be a call", expression_call_p(e));
3123 
3124  if (strcmp(entity_local_name(f1), "ERR=") == 0 ||
3125  strcmp(entity_local_name(f1), "END=") == 0) {
3126  expression ne = EXPRESSION(CAR(CDR(ce))); /* Next Expression */
3128 
3129  pips_assert("expression ne must be a call", expression_call_p(ne));
3130  pips_assert("l is a label", entity_label_p(l));
3131 
3132  *tl = CONS(ENTITY, l, *tl);
3133  }
3134  }
3135  }
3136  /* No need to go down in call statements */
3137  found = true;
3138  }
3139 
3140  return !found;
3141 }
3142 
3143 /* Look for labels appearing in END= or ERR= IO clauses and allocate a
3144  label list. */
3146 {
3147  list ll = NIL; /* Label List */
3148 
3150 
3151  return ll;
3152 }
3153 
3154 static bool collect_labels(statement s, list * pll)
3155 {
3156  entity l = statement_label(s);
3157  if(!entity_empty_label_p(l))
3158  *pll = CONS(ENTITY, l, *pll);
3159  return true;
3160 }
3161 
3162 
3163 /* Look for non-empty labels appearing directly or indirectly and allocate a
3164  label list.
3165 
3166  The code is assumed correct. Usage of labels, for instance in
3167  Fortran IOs, are not checked. Only the statement label field is checked.
3168  */
3170 {
3171  list ll = NIL; /* Label List */
3172 
3173  gen_context_recurse(s, (void *) &ll, statement_domain,
3175 
3176  /* To have labels in order of appearance */
3177  ll = gen_nreverse(ll);
3178 
3179  return ll;
3180 }
3181 
3182 ␌
3183 /* Make sure that s and all its substatements are defined
3184 
3185  @addtogroup statement_predicate
3186 */
3187 static bool undefined_statement_found_p(statement s, bool * p_undefined_p)
3188 {
3189  if(!(* p_undefined_p)) {
3190  ifdebug(9) {
3191  fprintf(stderr, "----\n");
3192  /* The recursive descent in s is fatal when there is a problem. */
3193  /* print_statement(s); */
3194  if(statement_undefined_p(s)) {
3195  /* You probably want a breakpoint here... */
3196  abort();
3197  }
3198  else {
3199  pips_debug(9,"checking statement %03td (%td,%td) with address %p:\n",
3202  }
3203  }
3204  * p_undefined_p = statement_undefined_p(s);
3205  }
3206  return !(* p_undefined_p);
3207 }
3208 
3209 
3210 /*
3211  @addtogroup statement_predicate
3212 */
3214 {
3215  bool undefined_p = false;
3216 
3217  gen_context_recurse(s, (void *) &undefined_p ,statement_domain,
3219  return !undefined_p;
3220 }
3221 
3222 
3223 typedef struct {
3227 
3228 /* Add the declarations of a statement to a list if not already here
3229 
3230  This function is indeed to be used by statement_to_declarations() and
3231  instruction_to_declarations() but not by its own.
3232 
3233  @return true (to go on diving in a gen_recurse())
3234 */
3236 {
3238  {
3240  if(!set_belong_p(ctxt->cache,e)) {
3242  set_add_element(ctxt->cache,ctxt->cache,e);
3243  }
3244  return false;/* no declaration in a declaration!*/
3245  }
3246  return true;
3247 }
3248 
3249 /* Get a list of all variables declared recursively within a statement.
3250  * It works for any newgen type, not only statements.
3251  * Warning: the list must be freed !
3252  */
3254 {
3256  gen_context_multi_recurse(s, &ctxt,
3259  NULL);
3260  set_free(ctxt.cache);
3262 }
3263 
3264 /* Returns the declarations contained in a list of statement. */
3266 {
3267  list tail = NIL; //< avoid a costly gen_nconc
3268  list head = NIL; //< by managing the tail by end
3269  FOREACH(STATEMENT,st,sl) {
3270  list s2d = statement_to_declarations(st);
3271  if(ENDP(head)) head=tail=s2d;
3272  else CDR(tail)=s2d;
3273  tail = gen_last(tail);
3274  }
3275  return head;
3276 }
3277 
3278 /* Get a list of all variables declared recursively within an instruction */
3280 {
3281  return statement_to_declarations(i);
3282 }
3283 
3284 ␌
3285 
3287 
3289 {
3290  list blocks = NIL; // list of statements
3291  control c_in = unstructured_control(u); // entry point of u
3292  list dl = NIL; // declaration list
3293 
3294  CONTROL_MAP(c,
3295  {
3298  dl = gen_nconc(dl, sdl);
3299  },
3300  c_in,
3301  blocks);
3302 
3304  return dl;
3305 }
3306 
3307 /* No recursive descent */
3309 {
3310  list sdl = NIL;
3311 
3312  if(declaration_statement_p(st)) {
3314  }
3315  else if(statement_unstructured_p(st)) {
3318  }
3319  return sdl;
3320 }
3321 
3322 /* Returns the declarations contained directly in the declaration
3323  statements of a list of statements.
3324 
3325  @param sl
3326  List of statements
3327 
3328  @return a newly allocated list of entities appearing in the statement
3329  declarations of the list. No recursive descent in loops or tests or
3330  sequences because only variables of the current scope are
3331  returned. Recursive descent in unstructured statements because
3332  their statements are in the same scope as the statements in list sl
3333 */
3335 {
3336  list dl = NIL;
3337  FOREACH(STATEMENT,st,sl) {
3339  // Derived entities may be declared several times
3340  list nsdl = NIL;
3341  FOREACH(ENTITY, e, sdl) {
3342  if(!gen_in_list_p(e, dl))
3343  nsdl = CONS(ENTITY, e, nsdl);
3344  }
3345  nsdl = gen_nreverse(nsdl);
3346  dl = gen_nconc(dl, nsdl);
3347  }
3348 
3349  return dl;
3350 }
3351 
3352 /* Returns the declarations contained directly in a statement s
3353 
3354  @param s
3355  any kind of statement
3356 
3357  @return a newly allocated list of entities appearing statement s.
3358  If s is a sequence, look for all declaration statements in the
3359  statement list of s.
3360 
3361  No recursive descent in loops or tests or sequences because only
3362  variables of the current scope are returned. Recursive descent in
3363  unstructured statements because their statements are in the same
3364  scope as the statements in list sl
3365 */
3367 {
3368  list dl = NIL;
3369  if(statement_block_p(s)) {
3370  list sl = statement_block(s);
3372  }
3373  else
3375  return dl;
3376 }
3377 ␌
3378 
3379 /************************************************************ STAT VARIABLES */
3380 
3381 // local struct
3382 typedef struct {
3385 } entities_t;
3386 
3388 {
3389  // a function may be referenced, eg in a function pointer assignment.
3390  entity var = reference_variable(r);
3391  if (!set_belong_p(vars->sents, var))
3392  {
3393  vars->lents = CONS(entity, var, vars->lents);
3394  set_add_element(vars->sents, vars->sents, var);
3395  }
3396  return true;
3397 }
3398 
3399 static bool add_loop_index_entity(loop l, entities_t * vars)
3400 {
3401  entity idx = loop_index(l);
3402  if (!set_belong_p(vars->sents, idx))
3403  {
3404  vars->lents = CONS(entity, idx, vars->lents);
3405  set_add_element(vars->sents, vars->sents, idx);
3406  }
3407  return true;
3408 }
3409 
3411 {
3413  {
3414  value init = entity_initial(var);
3415  if (value_expression_p(init))
3416  // only references down there
3419  }
3420  return true;
3421 }
3422 
3423 /* Get a list of all variables referenced recursively within a statement:
3424  * - as reference in expressions in the code
3425  * - as loop indexes, which may not be used anywhere else
3426  * - as references in initializations
3427  */
3429 {
3430  entities_t vars;
3431  vars.lents = NIL;
3432  vars.sents = set_make(set_pointer);
3433 
3435  (s, &vars,
3439  NULL);
3440 
3441  set_free(vars.sents), vars.sents = NULL;
3442  return gen_nreverse(vars.lents);
3443 }
3444 
3445 /***************************************************** USER FUNCTIONS CALLED */
3446 
3448 {
3449  /* FI: I do not know what should be done for pointers to function,
3450  assuming they can be called. */
3451  entity f = call_function(c);
3452  value fv = entity_initial(f);
3453 
3454  if(!set_belong_p(funcs->sents, f) && value_code_p(fv))
3455  {
3456  funcs->lents = CONS(entity, f, funcs->lents);
3457  set_add_element(funcs->sents, funcs->sents, f);
3458  }
3459  return true;
3460 }
3461 
3463 {
3465  {
3466  value init = entity_initial(var);
3467  if (value_expression_p(init))
3470  }
3471  return true;
3472 }
3473 
3474 /* Get a list of all user function called recursively within a statement:
3475  * - in the code
3476  * - in initialisations
3477  */
3479 {
3480  entities_t funcs;
3481  funcs.lents = NIL;
3482  funcs.sents = set_make(set_pointer);
3483 
3485  (s, &funcs,
3488  NULL);
3489 
3490  set_free(funcs.sents), funcs.sents = NULL;
3491  return gen_nreverse(funcs.lents);
3492 }
3493 
3494 /* Return first reference found */
3497 
3499 {
3500  bool result= true;
3502  entity rv = reference_variable(r);
3503  if (rv == variable_searched) {
3505  result = false;
3506  }
3507  }
3508  else
3509  result = false;
3510 
3511  return result;
3512 }
3513 
3514 
3516 {
3517  bool result = true;
3519  {
3520  if (declaration_statement_p(st))
3521  {
3523  {
3524  value init_val = entity_initial(decl);
3525  if (! value_undefined_p(init_val))
3526  {
3529  {
3530  result = false;
3531  break;
3532  }
3533  }
3534  }
3535  }
3536  }
3537  else
3538  result = false;
3539 
3540  return result;
3541 }
3542 
3544 {
3547  variable_searched = v;
3551  NULL);
3555  return r;
3556 }
3557 
3558 static int reference_count = -1;
3559 
3560 /* Count static references */
3562 {
3563  bool result= true;
3564  entity rv = reference_variable(r);
3565  if (rv == variable_searched) {
3566  reference_count++;
3567  }
3568  return result;
3569 }
3570 
3572 {
3573  reference_count = 0;
3574  variable_searched = v;
3577  return reference_count;
3578 }
3579 
3580 /* Estimate count of dynamic references */
3581 static int loop_depth;
3582 
3583 
3585 {
3586  bool result= true;
3587  entity rv = reference_variable(r);
3588  if (rv == variable_searched) {
3589  /* 10: arbitrary value for references nested in at least one loop */
3590  reference_count += (loop_depth > 0 ? 10 : 1 );
3591  }
3592  return result;
3593 }
3594 
3596 {
3597  if (declaration_statement_p(st))
3598  {
3600  {
3601  value init_val = entity_initial(decl);
3602  if (! value_undefined_p(init_val))
3603  {
3605  }
3606  }
3607  }
3608  return true;
3609 }
3610 
3611 
3612 /* This function checks reference to proper elements, not slices */
3614 {
3615  bool result= true;
3616  entity rv = reference_variable(r);
3617  if (rv == variable_searched) {
3618  list inds = reference_indices(r);
3619  size_t d = type_depth(ultimate_type(entity_type(rv)));
3620  if (gen_length(inds) == d) {
3621  /* 10: arbitrary value for references nested in at least one loop */
3622  reference_count += (loop_depth > 0 ? 10 : 1 );
3623  }
3624  }
3625  return result;
3626 }
3627 
3629 {
3630  if (declaration_statement_p(st))
3631  {
3633  {
3634  value init_val = entity_initial(decl);
3635  if (! value_undefined_p(init_val))
3636  {
3638  }
3639  }
3640  }
3641  return true;
3642 }
3643 
3644 static bool count_loop_in(loop __attribute__ ((unused)) l)
3645 {
3646  loop_depth++;
3647  return true;
3648 }
3649 
3650 static void count_loop_out(loop __attribute__ ((unused)) l)
3651 {
3652  loop_depth--;
3653 }
3654 
3656 {
3657  reference_count = 0;
3658  loop_depth = 0;
3659  variable_searched = v;
3664  return reference_count;
3665 }
3667 {
3668  reference_count = 0;
3669  loop_depth = 0;
3670  variable_searched = v;
3675  return reference_count;
3676 }
3677 /**
3678  * @name get_statement_depth and its auxilary functions
3679  * @{ */
3680 
3681 static bool is_substatement = false;
3682 
3684 {
3685  if( !is_substatement)
3686  is_substatement = (some==s);
3687  return !is_substatement;
3688 }
3689 
3690 /**
3691  * @brief search a statement inside a statement
3692  *
3693  * @param s searched statement
3694  * @param root where to start searching from
3695  *
3696  * @return true if found
3697  *
3698  * NL: What is the difference with statement_in_statement_p?
3699  * statement_in_statement_p certainly be better to keep, no global variable
3700  * and use of gen_recurse_stop to stop the recursion
3701  */
3703 {
3704  is_substatement= false;
3705  //printf("searching::::::::::::::\n");
3706  //print_statement(s);
3707  //printf("inside::::::::::::\n");
3708  //print_statement(root);
3710  //if(is_substatement) printf(":::::::::found !\n");
3711  //else printf("::::::::not found !\n");
3712  return is_substatement;
3713 }
3714 
3715 /**
3716  * @brief computes the block-depth of a statement
3717  * NOT INTENDED to generate entity name declared at particular block level :
3718  * The block scope depends on the number of different blocks at the same depth !
3719  *
3720  * @param s statement we compute the depth of
3721  * @param root outer statement containing s
3722  *
3723  * @return positive integer
3724  */
3726 {
3727  if( s == root )
3728  return 0;
3729  else {
3731  switch(instruction_tag(i))
3732  {
3734  {
3736  {
3738  return 1+get_statement_depth(s,stmt);
3739  }
3740  pips_internal_error("you should never reach this point");
3741  return -1;
3742  }
3743  case is_instruction_test:
3744  return
3748  case is_instruction_loop:
3755  pips_internal_error("not implemented for unstructured");
3756  return -1;
3757  default:
3758  pips_internal_error("you should never reach this point");
3759  return -1;
3760  };
3761  }
3762 
3763 }
3764 
3765 
3766 
3767 
3768 
3769 /**
3770  * @name statement finders
3771  * find statements with particular constraints
3772  * @{ */
3773 
3774 /**
3775  * structure used by find_statements_with_label_walker
3776  */
3777 struct fswl {
3778  statement st; ///< statement matching condition
3779  entity key; ///< used for the condition
3780 };
3781 
3782 /**
3783  * helper to find statement with a particular label
3784  * as label should be unique, the function stops once a statement is found
3785  *
3786  * @param s statement to inspect
3787  * @param p struct containing the list to fill and the label to search
3788  *
3789  * @return
3790  */
3792 {
3793  if( same_entity_p(statement_label(s),p->key) ||
3795  {
3796  p->st=s;
3797  gen_recurse_stop(NULL);
3798  }
3799  return true;
3800 }
3801 
3802 /**
3803  * find a statement in s with entity label
3804  *
3805  * @param s statement to search into
3806  * @param label label of the searched statement
3807  *
3808  * @return statement found or statement_undefined
3809  */
3811 {
3812  struct fswl p = { statement_undefined , label };
3814  return p.st;
3815 }
3816 statement find_statement_from_label_name(statement s, const char *module_name ,const char * label_name)
3817 {
3818  entity label = find_label_entity(module_name,label_name);
3819  if(entity_undefined_p(label))
3820  return statement_undefined;
3821  else
3822  return find_statement_from_label(s,label);
3823 }
3824 
3825 
3826 /*
3827  @addtogroup statement_predicate
3828 */
3829 
3830 /* Test if a statement has some pragma
3831 
3832  @param s is the statement to test
3833 
3834  @return true if a statement has a pragma
3835 */
3838  FOREACH(EXTENSION, ex, exs) {
3839  if(extension_pragma_p(ex)) {
3840  return true;
3841  }
3842  }
3843  return false;
3844 }
3845 
3846 /**
3847  * get the list of pragma of a statement s
3848  * \param s the statement to work on
3849  * \return list of pragma of the statement s, NIL if the statement doesn't have pragma
3850  */
3852  list lpragmas = NIL;
3855  FOREACH(EXTENSION, ex, exs) {
3856  if(extension_pragma_p(ex)) {
3857  lpragmas = CONS(PRAGMA, extension_pragma(ex), lpragmas);
3858  }
3859  }
3860  return gen_nreverse(lpragmas);
3861 }
3862 
3863 /* Get the extension of a statement with pragma beginning with a prefix
3864 
3865  @param s is the statement to work on
3866 
3867  @param seed is the prefix a pragma has to begin with to be selected
3868 
3869  @return the first extension matching the pragma
3870 */
3872 {
3874  FOREACH(EXTENSION,ex,exs)
3875  {
3876  pragma pr = extension_pragma(ex);
3877  if(pragma_string_p(pr) && strstr(pragma_string(pr),seed))
3878  {
3879  return ex;
3880  }
3881  }
3882  return NULL;
3883 }
3884 
3885 /**
3886  * used to pass parameters to find_statements_with_comment_walker
3887  */
3888 struct fswp {
3890  const char*begin;
3891 };
3892 
3894 {
3896  {
3897  p->l=CONS(STATEMENT,s,p->l);
3898  gen_recurse_stop(NULL);
3899  }
3900  return true;
3901 }
3902 
3903 
3904 /* Get a list of statements with pragma begining with a prefix
3905 
3906  @param s is the statement to start to recurse
3907 
3908  @param begin is the prefix a pragma has to begin with to be selected
3909 
3910  @return a list of statement
3911 */
3913 {
3914  struct fswp p = { NIL, begin };
3916  return gen_nreverse(p.l);
3917 }
3918 
3919 
3920 static bool look_for_user_call(call c, bool * user_call_p)
3921 {
3922  entity f = call_function(c);
3923  bool go_on_p = true;
3924 
3925  if(value_code_p(entity_initial(f))) {
3926  * user_call_p = true;
3927  go_on_p = false;
3928  }
3929  return go_on_p;
3930 }
3931 
3932 /* Check if a statement s contains a call to a user-defined
3933  function. This may be useful because PIPS does not contain a
3934  control effect analysis and because a user-defined function can
3935  hide a control effect such as exit(), abort() or STOP.
3936 
3937  @addtogroup statement_predicate
3938 */
3940 {
3941  bool user_call_p = false;
3943  return user_call_p;
3944 }
3945 
3946 static bool look_for_control_effects(call c, bool * control_effect_p)
3947 {
3948  entity f = call_function(c);
3949  bool go_on_p = true;
3950  value fv = entity_initial(f);
3951 
3952  if(value_code_p(fv)) {
3953  * control_effect_p = true;
3954  go_on_p = false;
3955  }
3956  else if(value_intrinsic_p(fv)) {
3959  || ENTITY_C_RETURN_P(f)
3960  || ENTITY_RETURN_P(f)
3963  * control_effect_p = true;
3964  go_on_p = false;
3965  }
3966  }
3967  return go_on_p;
3968 }
3969 
3970 /* Check if a statement s contains a call to a user-defined function
3971  or to an intrinsic with control effects. This may be useful because
3972  PIPS does not contain a control effect analysis and because a
3973  user-defined function can hide a control effect such as exit(),
3974  abort() or STOP.
3975 
3976  @addtogroup statement_predicate
3977 */
3979 {
3980  bool control_effect_p = false;
3981 
3982  /* Preserve branch targets, without checking if they are useful or
3983  not because it can be done by another pass */
3984  control_effect_p = !entity_empty_label_p(statement_label(s));
3985 
3986  if(!control_effect_p) {
3987  /* These statements may hide a non-terminating loop. I assume that
3988  do loops always terminate. They also always have a memory
3989  write effect for the index, which may not be true for the
3990  other kinds of loops. Unstructured could be tested to see if
3991  they have a syntactical control cycle or not. */
3992  control_effect_p = statement_whileloop_p(s) || statement_forloop_p(s)
3994  if(!control_effect_p)
3996  }
3997 
3998  return control_effect_p;
3999 }
4000 
4001 
4002 static bool look_for_exiting_intrinsic_calls(call c, bool * control_effect_p)
4003 {
4004  entity f = call_function(c);
4005  bool go_on_p = true;
4006  value fv = entity_initial(f);
4007 
4008  if(value_intrinsic_p(fv)) {
4011  || ENTITY_C_RETURN_P(f)
4012  || ENTITY_RETURN_P(f)
4015  * control_effect_p = true;
4016  go_on_p = false;
4017  }
4018  }
4019  return go_on_p;
4020 }
4021 
4023 {
4024  bool control_effect_p = false;
4025 
4026  if(!control_effect_p)
4028 
4029  return control_effect_p;
4030 }
4031 
4032 /* Make (a bit more) sure that s is gen_defined_p in spite of poor
4033  decision for empty fields and that strdup can be used on the string
4034  fields. */
4036 {
4038  || statement_decls_text(s)==NULL)
4039  statement_decls_text(s) = strdup("");
4041  || statement_comments(s)==NULL)
4042  statement_comments(s) = strdup("");
4043  return s;
4044 }
4045 /** @} */
4046 
4047 struct sb {
4049  bool found_p;
4050 };
4051 
4053 {
4054  // FI: no cycle between ri-util and prettyprint
4055  /* ifdebug(7) { */
4056  /* pips_debug(7,"considering statement:\n"); */
4057  /* print_statement(st); */
4058  /* } */
4059  if(sb->searched_statement==st)
4060  {
4061  sb->found_p=true; gen_recurse_stop(0);
4062  }
4063  return true;
4064 }
4065 
4066 /* Look if a statement is another one
4067 
4068  @param s is the potentially inside statement
4069 
4070  @param st is the outside statement
4071 
4072  @return true is @p s is inside @p st
4073 
4074  @addtogroup statement_predicate
4075 */
4077 {
4078  struct sb sb;
4079  sb.searched_statement = s;
4080  sb.found_p = false;
4082  return sb.found_p;
4083 }
4084 
4085 
4086 /* Look if at least one statement of a list of statements is in another
4087  one
4088 
4089  @param l is the list of statements
4090 
4091  @param st is the outside statement
4092 
4093  @return true is at least one statement of @p l is inside @p st
4094 
4095  @addtogroup statement_predicate
4096 */
4098 {
4099  FOREACH(STATEMENT,st,l)
4100  if(statement_in_statement_p(s,st)) return true;
4101  return false;
4102 }
4103 
4104 
4108  bool found_p;
4109 };
4110 
4112 {
4114  if(instruction_sequence_p(i)) {
4116  //This code come from search_sequence_containing
4117  MAP (STATEMENT, s2, {
4118  if (s2 == ctx->old_stat) {
4119  ctx->found_p = true;
4120  }
4121  }, stats_list );
4122 
4123  if (ctx->found_p == true) {
4124  //This code come from replace_in_sequence_statement_with
4125  list new_stats_list = NIL;
4126 
4127  MAP (STATEMENT, s, {
4128  ifdebug(7) {
4129  pips_debug(7, "Iterate on statement %"_intFMT"\n", statement_number(s));
4130  // NO CYCLE! print_statement(s);
4131  }
4132  if (s == ctx->old_stat) {
4133  pips_debug(7, "Replace this statement:\n");
4134  new_stats_list = CONS(STATEMENT,ctx->new_stat,new_stats_list);
4135  }
4136  else {
4137  pips_debug(7, "Keep this statement:\n");
4138  new_stats_list = CONS(STATEMENT,s,new_stats_list);
4139  }
4140  }, stats_list);
4141 
4143  //NL: it can make some bug if we had a exploration of stats_list outside this function?
4144  //gen_free_list(stats_list);
4145  gen_recurse_stop(0);
4146  }
4147  }
4148  else if(instruction_test_p(i)) {
4149  test t = instruction_test(i);
4150  if (test_true(t) == ctx->old_stat) {
4151  ctx->found_p = true;
4152  test_true(t) = ctx->new_stat;
4153  gen_recurse_stop(0);
4154  }
4155  else if (test_false(t) == ctx->old_stat) {
4156  ctx->found_p = true;
4157  test_false(t) = ctx->new_stat;
4158  gen_recurse_stop(0);
4159  }
4160  }
4161  else if(instruction_loop_p(i)) {
4162  loop l = instruction_loop(i);
4163  if (loop_body(l) == ctx->old_stat) {
4164  ctx->found_p = true;
4165  loop_body(l) = ctx->new_stat;
4166  gen_recurse_stop(0);
4167  }
4168  }
4169  else if(instruction_whileloop_p(i)) {
4171  if (whileloop_body(l) == ctx->old_stat) {
4172  ctx->found_p = true;
4173  whileloop_body(l) = ctx->new_stat;
4174  gen_recurse_stop(0);
4175  }
4176  }
4177  else if(instruction_forloop_p(i)) {
4179  if (forloop_body(l) == ctx->old_stat) {
4180  ctx->found_p = true;
4181  forloop_body(l) = ctx->new_stat;
4182  gen_recurse_stop(0);
4183  }
4184  }
4185  else if(instruction_multitest_p(i)) {
4187  if (multitest_body(mt) == ctx->old_stat) {
4188  ctx->found_p = true;
4189  multitest_body(mt) = ctx->new_stat;
4190  gen_recurse_stop(0);
4191  }
4192  }
4193  else if(instruction_goto_p(i)) {
4194  if (instruction_goto(i) == ctx->old_stat) {
4195  ctx->found_p = true;
4196  instruction_goto(i) = ctx->new_stat;
4197  gen_recurse_stop(0);
4198  }
4199  }
4200  else if(instruction_unstructured_p(i)) {
4202  if (control_statement(unstructured_entry(u)) == ctx->old_stat) {
4203  ctx->found_p = true;
4205  gen_recurse_stop(0);
4206  }
4207  else if (control_statement(unstructured_exit(u)) == ctx->old_stat) {
4208  ctx->found_p = true;
4210  gen_recurse_stop(0);
4211  }
4212  }
4213  else if(instruction_call_p(i) || instruction_expression_p(i)) {
4214  //nothing to do
4215  }
4216  else {
4217  pips_internal_error("unknown instruction tag %d", instruction_tag(i));
4218  }
4219 
4220  return true;
4221 }
4222 
4223 
4224 /**
4225  * replace old_stat by new_stat in root_stat
4226  * this pass does not free old_stat
4227  * similar to replace_in_sequence_statement_with() in phrase/phrase_tools.c
4228  * but without the constraint that old_stat is in a sequence
4229  * \param old_stat statement to be replaced
4230  * \param new_stat statement that will replace old_stat
4231  * \param root_stat statement where old_stat is searched to be replaced
4232  * \return true if old_stat is found and replaced by new_stat
4233  * think to freed old_stat outside this function if the return is true
4234  */
4236  statement new_stat,
4237  statement root_stat)
4238 {
4239  pips_debug(5, "BEGIN\n");
4240 
4241  struct replace_statement_context ctx;
4242  ctx.new_stat = new_stat;
4243  ctx.old_stat = old_stat;
4244  ctx.found_p = false;
4245 
4246  gen_context_recurse(root_stat, &ctx,
4248 
4249  if (!ctx.found_p) {
4250  pips_user_warning("does not found the statement to replace.\n");
4251  }
4252 
4253  pips_debug(5, "END\n");
4254  return ctx.found_p;
4255 }
4256 
4257 
4258 /* That's all folks */
4259 
4260 /** @} */
4261 
4262 /* purge a statement from its extensions */
4267 }
4268 /**
4269  * @brief remove the label of a statement if the statement is not
4270  * unstructured. labels on fortran loops and Fortran return are also
4271  * preserved
4272  *
4273  * @param s statement considered
4274  */
4276 {
4278  if (!instruction_unstructured_p(i) &&
4280  {
4281  // under pyps, do not remove loop label like this */
4282  if (!(get_bool_property("PYPS") && instruction_loop_p(i)))
4283  {
4286  {
4287  // SG: should free_entity?
4288  *changed = true;
4290 
4291  // OK but guarded by previous test
4292  if (instruction_loop_p(i))
4294  if( instruction_whileloop_p(i) )
4296  }
4297  }
4298  }
4299 }
4300 
4301 /* return true if s is enclosed in stmt
4302  * NL: What is the difference with statement_in_statement_p?
4303  * */
4305 {
4306  if(!found_p){
4308  return true;
4309  else
4310  {
4312  switch(instruction_tag(inst)) {
4313  case is_instruction_block: {
4314  bool bs = found_p;
4315  MAPL( stmt_ptr,
4316  {
4317  statement local_stmt = STATEMENT(CAR( stmt_ptr ));
4318  bs = bs || belong_to_statement(local_stmt, s, found_p);
4319  },
4320  instruction_block( inst ) );
4321  return bs;
4322  }
4323  case is_instruction_test :{
4324  test t = instruction_test(inst);
4325  bool bt = found_p || belong_to_statement(test_true(t), s, found_p);
4326  return bt || belong_to_statement(test_false(t), s, found_p);
4327  break;
4328  }
4329  case is_instruction_loop : {
4330  loop l = statement_loop(stmt);
4331  statement body = loop_body(l);
4332  return found_p || belong_to_statement(body, s, found_p);
4333  break;
4334  }
4335  case is_instruction_forloop :{
4337  statement body = forloop_body(l);
4338  return found_p || belong_to_statement(body, s, found_p);
4339  break;
4340  }
4341  case is_instruction_whileloop : {
4343  statement body = whileloop_body(l);
4344  return found_p || belong_to_statement(body, s, found_p);
4345  break;
4346  }
4347  case is_instruction_call:
4348  return found_p || false;
4349  break;
4350  default:
4351  break;
4352  }
4353  }
4354  }
4355  else return true;
4356  return found_p;
4357 }
4358 
4359 /* Find the label associated with the last statement executed within s. */
4361 {
4362  entity fsl = entity_undefined;
4364  list l = list_undefined;
4365 
4366  switch(instruction_tag(i)) {
4367 
4368  case is_instruction_block:
4369  if(!ENDP(l=gen_last(instruction_block(i)))) {
4370  fsl = statement_label(STATEMENT(CAR(l)));
4371  }
4372  else {
4373  /* If empty blocks are allowed, we've recursed one statement too
4374  far. */
4375  pips_internal_error("Useless empty sequence. Unexpected in controlized code.");
4376  }
4377  break;
4378 
4379  case is_instruction_test:
4380  /* There cannot be a final statement. The test itself is the final
4381  instruction. */
4382  fsl = statement_label(s);
4383  break;
4384 
4385  case is_instruction_loop:
4387  break;
4388 
4389  case is_instruction_goto:
4390  pips_internal_error("Controlized code should not contain GO TO statements");
4391  break;
4392 
4393  case is_instruction_call:
4394  fsl = statement_label(s);
4395  break;
4396 
4398  /* Must be the label of the exit node. */
4401  break;
4402 
4403  default:
4404  pips_internal_error("Unknown instruction tag: %d",
4405  instruction_tag(i));
4406  }
4407 
4408  /* fsl should be either a meaningful label or the empty label */
4409  if(entity_undefined_p(fsl)) {
4410  pips_internal_error("Undefined final label");
4411  }
4412 
4413  return fsl;
4414 }
4415 
4416 
4417 /* @brief Start a single line comment
4418  * @return a string containing the begin of a comment line, language dependent
4419  */
4421  switch(t) {
4422  case is_language_c: return "//";
4423  case is_language_fortran: return "C";
4424  case is_language_fortran95: return "!";
4425  default: pips_internal_error("language unknown not handled"); return NULL ;
4426  }
4427 }
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
instruction make_instruction_loop(loop _field_)
Definition: ri.c:1175
evaluation make_evaluation_before(void)
Definition: ri.c:786
call make_call(entity a1, list a2)
Definition: ri.c:269
instruction make_instruction_forloop(forloop _field_)
Definition: ri.c:1193
whileloop make_whileloop(expression a1, statement a2, entity a3, evaluation a4)
Definition: ri.c:2937
loop make_loop(entity a1, range a2, statement a3, entity a4, execution a5, list a6)
Definition: ri.c:1301
instruction make_instruction_expression(expression _field_)
Definition: ri.c:1196
void free_extensions(extensions p)
Definition: ri.c:950
void extend_persistant_statement_to_int(persistant_statement_to_int f, statement k, intptr_t v)
Definition: ri.c:1660
bool statement_consistent_p(statement p)
Definition: ri.c:2195
test make_test(expression a1, statement a2, statement a3)
Definition: ri.c:2607
bool range_consistent_p(range p)
Definition: ri.c:2014
bool forloop_consistent_p(forloop p)
Definition: ri.c:998
extensions make_extensions(list a)
Definition: ri.c:983
execution make_execution_sequential(void)
Definition: ri.c:841
statement make_statement(entity a1, intptr_t a2, intptr_t a3, string a4, instruction a5, list a6, string a7, extensions a8, synchronization a9)
Definition: ri.c:2222
instruction make_instruction_sequence(sequence _field_)
Definition: ri.c:1169
instruction make_instruction_test(test _field_)
Definition: ri.c:1172
instruction make_instruction_call(call _field_)
Definition: ri.c:1184
void free_instruction(instruction p)
Definition: ri.c:1118
instruction make_instruction(enum instruction_utype tag, void *val)
Definition: ri.c:1166
reference copy_reference(reference p)
REFERENCE.
Definition: ri.c:2047
list gen_statement_cons(statement p, list l)
Definition: ri.c:2202
synchronization make_synchronization_none(void)
Definition: ri.c:2424
sequence make_sequence(list a)
Definition: ri.c:2125
persistant_statement_to_int make_persistant_statement_to_int(void)
Definition: ri.c:1651
extensions copy_extensions(extensions p)
EXTENSIONS.
Definition: ri.c:947
instruction make_instruction_whileloop(whileloop _field_)
Definition: ri.c:1178
void free_statement(statement p)
Definition: ri.c:2189
forloop make_forloop(expression a1, expression a2, expression a3, statement a4)
Definition: ri.c:1025
evaluation make_evaluation_after(void)
Definition: ri.c:789
bool test_consistent_p(test p)
Definition: ri.c:2580
range make_range(expression a1, expression a2, expression a3)
Definition: ri.c:2041
#define error(fun, msg)
NewGen interface with C3 type Psysteme for PIPS project.
Definition: Psc.c:78
struct _newgen_struct_entity_ * entity
Definition: abc_private.h:14
FILE * c_in
Definition: c_syntax.h:291
bool clean_up_sequences(statement s)
Recursively clean up the statement sequences by fusing them if possible and by removing useless one.
struct _newgen_struct_statement_ * statement
Definition: cloning.h:21
static hash_table nts
Definition: prettyprint.c:63
static list blocks
lisp of loops
expression MakeCharacterConstantExpression(string s)
END_EOLE.
Definition: constant.c:573
entity MakeConstant(string name, tag bt)
Make a Fortran constant.
Definition: constant.c:351
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
static void comment(string_buffer code, spoc_hardware_type hw, dagvtx v, int stage, int side, bool flip)
Definition: freia_spoc.c:52
#define gen_context_recurse(start, ctxt, domain_number, flt, rwt)
Definition: genC.h:285
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
void gen_full_free_list(list l)
Definition: genClib.c:1023
void free(void *)
statement make_statement_from_statement_list_or_empty_block(list l)
Build a statement sequence from a statement list.
Definition: statement.c:700
statement make_block_statement(list body)
Make a block statement from a list of statement.
Definition: statement.c:616
statement make_statement_from_statement_list(list l)
Build a statement sequence from a statement list.
Definition: statement.c:719
statement instruction_to_statement(instruction instr)
Build a statement from a give instruction.
Definition: statement.c:597
statement make_statement_from_statement_varargs_list(statement s,...)
Build a statement sequence from a statement NULL-terminated varargs list.
Definition: statement.c:735
void copy_statement_attributes(statement from, statement to)
Copy all the attributes from one statement to another one.
Definition: statement.c:678
statement make_empty_statement_with_declarations_and_comments(list d, string dt, string c)
Build an empty statement with declaration list, declaration text and comment.
Definition: statement.c:638
statement make_empty_block_statement()
Build an empty statement (block/sequence)
Definition: statement.c:625
void move_statement_attributes(statement from, statement to)
Move all the attributes from one statement to another one.
Definition: statement.c:657
statement make_block_with_stmt_if_not_already(statement stmt)
Build a statement block from a statement if not already a statement block.
Definition: statement.c:768
#define CONTROL_MAP(ctl, code, c, list)
Macro to walk through all the controls reachable from a given control node of an unstructured.
#define FORWARD_CONTROL_MAP(ctl, code, c, list)
Walk through all the controls forward-reachable from a given control node of an unstructured.
entity get_current_module_entity(void)
Get the entity of the current module.
Definition: static.c:85
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_context_multi_recurse(void *o, void *context,...)
Multi-recursion with context function visitor.
Definition: genClib.c:3373
void gen_null2(__attribute__((unused)) void *u1, __attribute__((unused)) void *u2)
idem with 2 args, to please overpeaky compiler checks
Definition: genClib.c:2758
bool gen_true2(__attribute__((unused)) gen_chunk *u1, __attribute__((unused)) void *u2)
Definition: genClib.c:2785
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
bool gen_false2(__attribute__((unused)) gen_chunk *u1, __attribute__((unused)) void *u2)
Definition: genClib.c:2801
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
instruction make_instruction_block(list statements)
Build an instruction block from a list of statements.
Definition: instruction.c:106
instruction make_assign_instruction(expression l, expression r)
Definition: instruction.c:87
bool instruction_assign_p(instruction i)
Test if an instruction is an assignment.
Definition: instruction.c:164
bool instruction_stop_p(instruction i)
Test if an instruction is a Fortran STOP.
Definition: instruction.c:214
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
bool exit_instruction_p(instruction i)
Definition: instruction.c:201
bool abort_instruction_p(instruction i)
Definition: instruction.c:205
bool instruction_format_p(instruction i)
Test if an instruction is a Fortran FORMAT.
Definition: instruction.c:222
bool native_instruction_p(instruction i, string op_name)
Test if an instruction is a native instruction of the language.
Definition: instruction.c:144
bool instruction_continue_p(instruction i)
Test if an instruction is a CONTINUE, that is the FORTRAN nop, the ";" in C or the "pass" in Python....
Definition: instruction.c:173
bool return_instruction_p(instruction i)
Test if an instruction is a C or Fortran "return".
Definition: instruction.c:185
bool C_return_instruction_p(instruction i)
Definition: instruction.c:196
bool fortran_return_instruction_p(instruction i)
Definition: instruction.c:191
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
#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
bool gen_once_p(list l)
FC: ARGH...O(n^2)!
Definition: list.c:758
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
list gen_last(list l)
Return the last element of a list.
Definition: list.c:578
bool gen_in_list_p(const void *vo, const list lx)
tell whether vo belongs to lx
Definition: list.c:734
#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 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 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
void gen_substitute_chunk_by_list(list *pl, const void *o, list sl)
substitute item o by list sl in list *pl, which is modified as a side effect.
Definition: list.c:591
expression statement_expression(statement s)
Get the expression of a statement.
Definition: statement.c:1446
sequence statement_sequence(statement s)
Get the sequence of a statement sequence.
Definition: statement.c:1328
multitest statement_multitest(statement s)
Get the multitest of a statement.
Definition: statement.c:1436
statement effective_test_true(test t)
returns the effective true branch of a test by skipping a possible sequence of one element.
Definition: statement.c:1358
list statement_block(statement s)
Get the list of block statements of a statement sequence.
Definition: statement.c:1338
loop statement_loop(statement s)
Get the loop of a statement.
Definition: statement.c:1374
test statement_test(statement s)
Get the test of a statement.
Definition: statement.c:1348
call statement_call(statement s)
Get the call of a statement.
Definition: statement.c:1406
whileloop statement_whileloop(statement s)
Get the whileloop of a statement.
Definition: statement.c:1383
statement statement_goto(statement s)
Get the goto of a statement.
Definition: statement.c:1396
forloop statement_forloop(statement s)
Get the forloop of a statement.
Definition: statement.c:1426
unstructured statement_unstructured(statement s)
Get the unstructured of a statement.
Definition: statement.c:1416
bool empty_statement_or_labelless_continue_p(statement st)
Return true if the statement is an empty instruction block without label or a continue without label ...
Definition: statement.c:446
bool statement_expression_p(statement s)
Definition: statement.c:384
bool unlabelled_statement_p(statement st)
Definition: statement.c:402
bool statement_goto_p(statement s)
Definition: statement.c:359
bool statement_multitest_p(statement s)
Definition: statement.c:379
bool statement_whileloop_p(statement s)
Definition: statement.c:354
bool statement_test_p(statement s)
Definition: statement.c:343
bool statement_call_p(statement s)
Definition: statement.c:364
bool statement_forloop_p(statement s)
Definition: statement.c:374
bool nop_statement_p(statement s)
Definition: statement.c:407
bool empty_statement_or_continue_p(statement st)
Return true if the statement is an empty instruction block or a continue or a recursive combination o...
Definition: statement.c:474
bool check_io_statement_p(statement s)
Definition: statement.c:528
bool empty_statement_p(statement st)
Test if a statement is empty.
Definition: statement.c:391
bool statement_loop_p(statement s)
Definition: statement.c:349
bool empty_statement_or_continue_without_comment_p(statement st)
Return true if the statement is an empty instruction block or a continue without comments or without ...
Definition: statement.c:497
bool statement_sequence_p(statement s)
Statement classes induced from instruction type.
Definition: statement.c:335
bool statement_unstructured_p(statement s)
Definition: statement.c:369
static bool look_for_exiting_intrinsic_calls(call c, bool *control_effect_p)
Definition: statement.c:4002
static bool declarations_count_element_references_to_v_p(statement st)
Definition: statement.c:3628
static bool count_loop_in(loop __attribute__((unused)) l)
Definition: statement.c:3644
static bool add_stat_called_in_inits(statement s, entities_t *funcs)
Definition: statement.c:3462
static bool declarations_count_references_to_v_p(statement st)
Definition: statement.c:3595
list gather_and_remove_all_format_statements(statement s)
Used to keep aside the FORMAT before many code transformation that could remove them either.
Definition: statement.c:2298
static char ** find_first_comment(statement s)
Find the first comment of a statement, if any.
Definition: statement.c:1801
statement apply_number_to_statement(hash_table nts, _int n)
Definition: statement.c:1495
static bool find_statements_with_pragma_walker(statement s, struct fswp *p)
Definition: statement.c:3893
bool format_statement_p(statement s)
Test if a statement is a Fortran FORMAT.
Definition: statement.c:273
hash_table allocate_number_to_statement()
Definition: statement.c:1540
statement make_any_print_statement(string message)
Generate a print of a constant character string on stderr for C or on stdout for Fortran.
Definition: statement.c:893
list statement_to_implicit_target_labels(statement s)
Look for labels appearing in END= or ERR= IO clauses and allocate a label list.
Definition: statement.c:3145
static bool find_statements_with_label_walker(statement s, struct fswl *p)
helper to find statement with a particular label as label should be unique, the function stops once a...
Definition: statement.c:3791
static bool cannot_be_empty(bool *statement_is_empty)
Definition: statement.c:70
statement make_assign_statement(expression l, expression r)
Definition: statement.c:583
statement add_initialization_information_to_declaration_statement(statement s, list iel)
The initialization expression list is integrated into the internal representation as an argument list...
Definition: statement.c:1119
int count_references_to_variable(statement s, entity v)
Definition: statement.c:3655
static bool first_reference_to_v_p(reference r)
Definition: statement.c:3498
static bool look_for_user_call(call c, bool *user_call_p)
Definition: statement.c:3920
static bool look_for_control_effects(call c, bool *control_effect_p)
Definition: statement.c:3946
entity statement_to_label(statement s)
See if statement s is labelled and can be reached by a GO TO.
Definition: statement.c:2090
bool comments_equal_p(string c1, string c2)
Definition: statement.c:116
statement add_declaration_statement_at_beginning(statement s, entity e)
Definition: statement.c:2795
#define ERROR_PREFIX
as name indicate, a comment is added.
Definition: statement.c:1937
void append_statement_to_block_statement(statement b, statement s)
Definition: statement.c:2586
list statement_to_referenced_entities(statement s)
Get a list of all variables referenced recursively within a statement:
Definition: statement.c:3428
void insert_comments_to_statement(statement s, const char *the_comments)
Insert a comment string (if non empty) at the beginning of the comments of a statement.
Definition: statement.c:1916
bool statement_contains_user_call_p(statement s)
Definition: statement.c:3939
statement update_statement_instruction(statement s, instruction i)
Replace the instruction in statement s by instruction i.
Definition: statement.c:3039
void put_a_comment_on_a_statement(statement s, string the_comments)
Similar to try_to_put_a_comment_on_a_statement() but insert a CONTINUE to put the comment on it if th...
Definition: statement.c:1863
int count_references_to_variable_element(statement s, entity v)
Definition: statement.c:3666
char ** find_first_statement_comment(statement s)
Find the first non-empty comment of a statement, if any returns a pointer to the comment if found,...
Definition: statement.c:1772
int count_static_references_to_variable(statement s, entity v)
Definition: statement.c:3571
statement make_print_statement(string message)
Make a Fortran print statement.
Definition: statement.c:835
statement make_whileloop_statement(expression condition, statement body, int line_number, bool before)
Build a while loop statement.
Definition: statement.c:1150
static bool replace_statement_walker(statement s, struct replace_statement_context *ctx)
Definition: statement.c:4111
void put_formats_at_module_beginning(statement s)
Transfer all the FORMATs at the very beginning of a module:
Definition: statement.c:2311
statement makeloopbody(loop l, statement s_old, bool inner_p)
statement makeloopbody(l, s_old) make a statement for a loop body, using the fields of a previously e...
Definition: statement.c:1641
static void count_loop_out(loop __attribute__((unused)) l)
Definition: statement.c:3650
bool statement_substatement_walker(statement some, statement s)
Definition: statement.c:3683
void fix_block_statement_declarations(statement s)
s is assumed to be a block statement and its declarations field is assumed to be correct,...
Definition: statement.c:2930
statement make_loop_statement(entity i, expression low, expression up, expression inc, statement b)
Build a loop statement.
Definition: statement.c:1181
static string default_generated_variable_commenter(__attribute__((unused)) entity e)
Definition: statement.c:2597
bool all_statements_defined_p(statement s)
Definition: statement.c:3213
static bool add_statement_declarations(statement s, add_statement_declarations_t *ctxt)
Add the declarations of a statement to a list if not already here.
Definition: statement.c:3235
bool unstructured_does_return(unstructured u)
Definition: statement.c:2254
void append_comments_to_statement(statement s, string the_comments)
Append a comment string (if non empty) to the comments of a statement, if the c.
Definition: statement.c:1889
bool try_to_put_a_comment_on_a_statement(statement s, string the_comments)
Put a comment on a statement in a safe way.
Definition: statement.c:1831
statement make_expression_statement(expression e)
Build a statement from a given expression.
Definition: statement.c:1308
#define PIPS_DECLARATION_COMMENT
Definition: statement.c:2595
string statement_identification(statement s)
Like external_statement_identification(), but with internal information, the hexadecimal address of t...
Definition: statement.c:1700
statement make_stop_statement(string message)
This function returns a Fortran stop statement with an error message.
Definition: statement.c:908
static bool add_loop_index_entity(loop l, entities_t *vars)
Definition: statement.c:3399
statement remove_declaration_statement(statement s, entity e)
Declarations are not only lists of entities, but also statement to carry the line number,...
Definition: statement.c:2966
static int current_line
Poor attempt at associating physical line numbers to statement.
Definition: statement.c:2405
list statements_to_declarations(list sl)
Returns the declarations contained in a list of statement.
Definition: statement.c:3265
bool declaration_statements_p(list sl)
Check that all statements contained in statement list sl are declaration statements.
Definition: statement.c:1099
static bool declarations_first_reference_to_v_p(statement st)
Definition: statement.c:3515
bool return_statement_p(statement s)
Test if a statement is a C or Fortran "return".
Definition: statement.c:172
bool statement_may_have_control_effects_p(statement s)
Definition: statement.c:3978
void put_formats_at_module_end(statement s)
Transfer all the FORMATs at the very end of a module:
Definition: statement.c:2328
bool exit_statement_p(statement s)
Definition: statement.c:177
list statement_to_called_user_entities(statement s)
Get a list of all user function called recursively within a statement:
Definition: statement.c:3478
int statement_to_comment_length(statement stmt)
Number of comment line directly attached to a statement.
Definition: statement.c:2375
string decls_text_dup(string dt)
Duplicate statement decls_text.
Definition: statement.c:574
list statement_to_declarations(void *s)
Get a list of all variables declared recursively within a statement.
Definition: statement.c:3253
static void up_counter(statement s)
Definition: statement.c:2433
string generated_variable_comment(entity e)
Definition: statement.c:2629
string(* generated_variable_commenter)(entity)
commenters are function used to add comments to pips-created variables they are handled as a limited ...
Definition: statement.c:2609
list statement_to_labels(statement s)
Look for non-empty labels appearing directly or indirectly and allocate a label list.
Definition: statement.c:3169
list find_statements_with_pragma(statement s, const char *begin)
Get a list of statements with pragma begining with a prefix.
Definition: statement.c:3912
statement make_declaration_statement(entity v, int sn, string cs)
Make one declaration statement.
Definition: statement.c:1091
statement make_call_statement(string function_name, list args, entity l, string c)
This function is limited to intrinsics calls...
Definition: statement.c:1274
list instruction_to_declarations(instruction i)
Get a list of all variables declared recursively within an instruction.
Definition: statement.c:3279
static bool gather_all_comments_of_a_statement_filter(statement s, string *all_comments)
Definition: statement.c:1740
bool statement_with_pragma_p(statement s)
Test if a statement has some pragma.
Definition: statement.c:3836
bool write_statement_p(statement s)
Definition: statement.c:281
static void update_number_to_statement(statement s)
Definition: statement.c:1479
bool figure_out_if_it_is_a_format(instruction i, bool *format_inside_statement_has_been_found)
Definition: statement.c:2343
void pop_generated_variable_commenter()
Definition: statement.c:2623
reference find_reference_to_variable(statement s, entity v)
Definition: statement.c:3543
bool stop_statement_p(statement s)
Test if a statement is a Fortran STOP.
Definition: statement.c:263
void add_one_line_of_comment(statement s, string format,...)
Definition: statement.c:1940
string external_statement_identification(statement s)
Does work neither with undefined statements nor with defined statements with undefined instructions.
Definition: statement.c:1671
static bool add_stat_called_user_entities(call c, entities_t *funcs)
Definition: statement.c:3447
statement add_comment_and_line_number(statement s, string sc, int sn)
Since block cannot carry comments nor line numbers, they must be moved to an internal continue statem...
Definition: statement.c:1980
static reference first_reference_to_v
Return first reference found.
Definition: statement.c:3495
static statement generic_add_declaration_statement(statement s, entity e, bool before_p)
Add a new declaration statement.
Definition: statement.c:2711
bool fortran_return_statement_p(statement s)
Test if a statement is a Fortran "return".
Definition: statement.c:188
list statement_to_direct_declarations(statement s)
Returns the declarations contained directly in a statement s.
Definition: statement.c:3366
statement make_C_print_statement(string message)
Definition: statement.c:852
static list unstructured_to_direct_declarations(unstructured u)
Definition: statement.c:3288
bool continue_statement_p(statement s)
Test if a statement is a CONTINUE, that is the FORTRAN nop, the ";" in C or the "pass" in Python....
Definition: statement.c:203
static bool call_filter(call c, bool *statement_is_empty)
Definition: statement.c:76
statement find_statement_from_label(statement s, entity label)
find a statement in s with entity label
Definition: statement.c:3810
statement make_declarations_statement(list idl, int sn, string cs)
Make a declaration(s) statement.
Definition: statement.c:990
static generated_variable_commenter generated_variable_commenters[MAX_COMMENTERS]
Definition: statement.c:2611
void insert_statement(statement s, statement s1, bool before)
This is the normal entry point.
Definition: statement.c:2570
bool empty_code_list_p(list l)
Definition: statement.c:99
persistant_statement_to_int statement_to_line_number(statement s)
Definition: statement.c:2460
string safe_statement_identification(statement s)
Definition: statement.c:1726
statement make_return_statement(entity module)
Definition: statement.c:779
static bool add_declaration_to_declaration_statement_p(statement s, string c, entity nv)
Check if declaration of variable nv can be added to the declaration list of statement s.
Definition: statement.c:2657
bool empty_code_p(statement s)
statement.c
Definition: statement.c:86
hash_table build_number_to_statement(hash_table nts, statement s)
Definition: statement.c:1516
bool assignment_statement_p(statement s)
Test if a statement is an assignment.
Definition: statement.c:135
#define MAX_COMMENTERS
Definition: statement.c:2603
static size_t nb_commenters
Definition: statement.c:2614
static bool is_substatement
Definition: statement.c:3681
void insert_statement_no_matter_what(statement s, statement s1, bool before)
Break the IR consistency or, at the very least, do not insert new declarations at the usual place,...
Definition: statement.c:2581
list statement_pragmas(statement s)
get the list of pragma of a statement s
Definition: statement.c:3851
instruction make_simple_Fortran_io_instruction(bool is_read_p, expression f, list io_list)
Derived from the Fortran parser code.
Definition: statement.c:807
statement add_declaration_statement_here(statement block_statement, statement s, entity e, bool before_p)
Add a new declaration statement (inspired by generic_add_declaration_statement)
Definition: statement.c:2839
static bool undefined_statement_found_p(statement s, bool *p_undefined_p)
Definition: statement.c:3187
static bool add_stat_referenced_entities(reference r, entities_t *vars)
Definition: statement.c:3387
statement make_exit_statement(int n, string errmess)
This function returns a statement ending with a C exit statement.
Definition: statement.c:926
static int loop_depth
Estimate count of dynamic references.
Definition: statement.c:3581
static persistant_statement_to_int stmt_to_line
Definition: statement.c:2406
static set duplicate_numbers
To keep track of duplicate numbers.
Definition: statement.c:1477
static void generic_insert_statement(statement s, statement s1, bool before)
insert statement s1 before or after statement s
Definition: statement.c:2494
string comments_dup(string comment)
functions to generate statements
Definition: statement.c:557
bool statement_possible_less_p(statement st1, statement st2)
Definition: statement.c:306
static bool count_static_references_to_v_p(reference r)
Count static references.
Definition: statement.c:3561
bool statement_less_p(statement st1, statement st2)
Definition: statement.c:288
static bool count_references_to_v_p(reference r)
Definition: statement.c:3584
statement make_continue_statement(entity l)
Definition: statement.c:953
static bool statement_in_statement_walker(statement st, struct sb *sb)
Definition: statement.c:4052
bool forloop_statement_p(statement s)
Definition: statement.c:209
static list internal_statement_to_direct_declarations(statement st)
No recursive descent.
Definition: statement.c:3308
string gather_all_comments_of_a_statement(statement s)
Gather all the comments recursively found in the given statement and return them in a strduped string...
Definition: statement.c:1760
extension get_extension_from_statement_with_pragma(statement s, const char *seed)
Get the extension of a statement with pragma beginning with a prefix.
Definition: statement.c:3871
bool C_return_statement_p(statement s)
Test if a statement is a C "return".
Definition: statement.c:194
void fix_statement_attributes_if_sequence(statement s)
Apply fix_sequence_statement_attributes() on the statement only if it really a sequence.
Definition: statement.c:2078
list statements_to_direct_declarations(list sl)
Returns the declarations contained directly in the declaration statements of a list of statements.
Definition: statement.c:3334
list declaration_statement_to_initializations(statement s)
Definition: statement.c:1128
static hash_table number_to_statement
Mapping from statement number to statement.
Definition: statement.c:1475
bool statement_replace_in_root_statement(statement old_stat, statement new_stat, statement root_stat)
replace old_stat by new_stat in root_stat this pass does not free old_stat similar to replace_in_sequ...
Definition: statement.c:4235
int get_statement_depth(statement s, statement root)
computes the block-depth of a statement NOT INTENDED to generate entity name declared at particular b...
Definition: statement.c:3725
statement add_declaration_statement(statement s, entity e)
Definition: statement.c:2790
bool assignment_block_or_statement_p(statement s)
Definition: statement.c:142
bool statement_in_statement_p(statement s, statement st)
Definition: statement.c:4076
statement clear_labels(statement s)
Get rid of all labels in controlized code before duplication.
Definition: statement.c:1560
bool empty_comments_p(const char *s)
Definition: statement.c:107
bool statement_with_empty_comment_p(statement s)
Return true if the statement has an empty statement:
Definition: statement.c:126
static bool find_implicit_goto(statement s, list *tl)
Definition: statement.c:3107
void clear_label(statement s)
Definition: statement.c:1568
statement normalize_statement(statement s)
Make (a bit more) sure that s is gen_defined_p in spite of poor decision for empty fields and that st...
Definition: statement.c:4035
statement find_statement_from_label_name(statement s, const char *module_name, const char *label_name)
Definition: statement.c:3816
statement make_test_statement(expression cond, statement truebody, statement falsebody)
Definition: statement.c:1248
static bool down_counter(statement s)
Definition: statement.c:2409
bool abort_statement_p(statement s)
Definition: statement.c:182
void gather_and_remove_all_format_statements_rewrite(statement s, list *all_formats)
Definition: statement.c:2270
statement make_plain_continue_statement()
Make a simple continue statement to be used as a NOP or ";" in C.
Definition: statement.c:964
static bool collect_labels(statement s, list *pll)
Definition: statement.c:3154
bool statement_may_contain_exiting_intrinsic_call_p(statement s)
Definition: statement.c:4022
static bool count_element_references_to_v_p(reference r)
This function checks reference to proper elements, not slices.
Definition: statement.c:3613
void push_generated_variable_commenter(string(*commenter)(entity))
Definition: statement.c:2616
statement add_label_to_statement(entity label, statement s, statement *labeled_statement)
Add a label to a statement.
Definition: statement.c:2158
statement st_make_nice_test(expression condition, list ltrue, list lfalse)
Definition: statement.c:1585
bool continue_statements_p(list sl)
Check that all statements contained in statement list sl are a continue statements.
Definition: statement.c:246
bool format_inside_statement_p(statement s)
Definition: statement.c:2360
static bool add_ref_entities_in_init(statement s, entities_t *vars)
Definition: statement.c:3410
static int reference_count
Definition: statement.c:3558
statement make_forloop_statement(expression init, expression cond, expression inc, statement body)
Definition: statement.c:1220
#define BUFSIZE
Definition: statement.c:1938
void statement_replace_with_statement_list(statement as, statement rs, list sl)
Assume that statement rs appears in statement as and replaced it by a statement list.
Definition: statement.c:3081
bool statement_substatement_p(statement s, statement root)
search a statement inside a statement
Definition: statement.c:3702
bool statement_does_return(statement s)
Returns false is no syntactic control path exits s (i.e.
Definition: statement.c:2195
void fix_sequence_statement_attributes(statement s)
Since blocks are not represented in Fortran, they cannot carry a label.
Definition: statement.c:2016
bool statement_in_statements_p(statement s, list l)
Definition: statement.c:4097
static entity variable_searched
Definition: statement.c:3496
bool declaration_statement_p(statement s)
Had to be optimized according to Beatrice Creusillet.
Definition: statement.c:224
statement searched_statement
Definition: statement.c:4048
void statement_remove_extensions(statement s)
That's all folks.
Definition: statement.c:4263
bool belong_to_statement(statement stmt, statement s, bool found_p)
return true if s is enclosed in stmt NL: What is the difference with statement_in_statement_p?
Definition: statement.c:4304
entity find_final_statement_label(statement s)
Find the label associated with the last statement executed within s.
Definition: statement.c:4360
list l
Definition: statement.c:3889
const char * begin
Definition: statement.c:3890
entity key
used for the condition
Definition: statement.c:3779
string comment_sentinel(tag t)
Start a single line comment.
Definition: statement.c:4420
void statement_remove_useless_label(statement s, bool *changed)
remove the label of a statement if the statement is not unstructured.
Definition: statement.c:4275
bool found_p
Definition: statement.c:4049
list lents
Definition: statement.c:3383
statement st
statement matching condition
Definition: statement.c:3778
static string commenter(__attribute__((unused)) entity e)
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
void * hash_get(const hash_table htp, const void *key)
this function retrieves in the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:449
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_del(hash_table htp, const void *key)
this function removes from the hash table pointed to by htp the couple whose key is equal to key.
Definition: hash.c:439
string instruction_identification(instruction i)
Return a constant string representing symbolically the instruction type.
Definition: instruction.c:284
#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 asprintf
Definition: misc-local.h:225
#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 exit(code)
Definition: misc-local.h:54
#define user_error(fn,...)
Definition: misc-local.h:265
#define abort()
Definition: misc-local.h:53
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
#define LABEL_PREFIX
Definition: naming-local.h:31
#define RETURN_LABEL_NAME
Definition: naming-local.h:106
#define LIST_DIRECTED_FORMAT_NAME
Definition: naming-local.h:97
#define TOP_LEVEL_MODULE_NAME
Module containing the global variables in Fortran and C.
Definition: naming-local.h:101
#define STATEMENT_ORDERING_UNDEFINED
mapping.h inclusion
Definition: newgen-local.h:35
string concatenate(const char *,...)
Return the concatenation of the given strings.
Definition: string.c:183
@ hash_int
Definition: newgen_hash.h:32
#define HASH_UNDEFINED_VALUE
value returned by hash_get() when the key is not found; could also be called HASH_KEY_NOT_FOUND,...
Definition: newgen_hash.h:56
#define hash_table_undefined
Value of an undefined hash_table.
Definition: newgen_hash.h:49
#define same_string_p(s1, s2)
#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_int
Definition: newgen_set.h:43
#define set_undefined_p(s)
Definition: newgen_set.h:49
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
#define string_undefined
Definition: newgen_types.h:40
#define _intFMT
Definition: newgen_types.h:57
char * string
STRING.
Definition: newgen_types.h:39
#define string_undefined_p(s)
Definition: newgen_types.h:41
intptr_t _int
_INT
Definition: newgen_types.h:53
int unit
UNIT.
Definition: newgen_types.h:97
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
static char * module
Definition: pips.c:74
static hash_table pl
properties are stored in this hash table (string -> property) for fast accesses.
Definition: properties.c:783
#define ENTITY_WRITE_P(e)
Fortran IO Management.
#define instruction_block_p(i)
#define READ_FUNCTION_NAME
#define ENTITY_ASSERT_SYSTEM_P(e)
include <assert.h>
#define STDERR_NAME
#define ORDERING_NUMBER(o)
#define ORDERING_STATEMENT(o)
#define ENTITY_CLOSE_P(e)
#define statement_block_p(stat)
#define ENTITY_CONTINUE_P(e)
#define RETURN_FUNCTION_NAME
#define ENTITY_EXIT_SYSTEM_P(e)
#define STATEMENT_NUMBER_UNDEFINED
default values
#define FPRINTF_FUNCTION_NAME
#define unstructured_control
After the modification in Newgen: unstructured = entry:control x exit:control we have create a macro ...
#define C_RETURN_FUNCTION_NAME
#define is_instruction_block
soft block->sequence transition
#define CONTINUE_FUNCTION_NAME
#define ENTITY_OPEN_P(e)
#define ENTITY_ABORT_SYSTEM_P(e)
#define WRITE_FUNCTION_NAME
#define ENTITY_C_RETURN_P(e)
#define STOP_FUNCTION_NAME
#define ENTITY_READ_P(e)
#define EXIT_FUNCTION_NAME
#define instruction_block(i)
#define make_statement_list(stats...)
easy list constructor
#define empty_comments
Empty comments (i.e.
#define ENTITY_RETURN_P(e)
#define NOT_OPERATOR_NAME
#define ENTITY_ASSERT_FAIL_SYSTEM_P(e)
bool entity_continue_p(entity f)
Definition: entity.c:1731
entity FindEntity(const char *package, const char *name)
Retrieve an entity from its package/module name and its local name.
Definition: entity.c:1503
const char * entity_local_name(entity e)
entity_local_name modified so that it does not core when used in vect_fprint, since someone thought t...
Definition: entity.c:453
bool entity_return_label_p(entity e)
Definition: entity.c:673
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
bool entity_label_p(entity e)
Definition: entity.c:678
entity entity_empty_label(void)
Definition: entity.c:1105
basic entity_basic(entity e)
return the basic associated to entity e if it's a function/variable/constant basic_undefined otherwis...
Definition: entity.c:1380
bool entity_field_p(entity e)
e is the field of a structure
Definition: entity.c:857
static int init
Maximal value set for Fortran 77.
Definition: entity.c:320
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
list entity_qualifiers(entity e)
return the qualifiers associated to entity e if it's a variable NIL otherwise
Definition: entity.c:1394
bool entity_empty_label_p(entity e)
Definition: entity.c:666
bool io_entity_p(entity e)
Several implicit entities are declared to define the implicit effects of IO statements.
Definition: entity.c:1139
bool fortran_module_p(entity m)
Test if a module is in Fortran.
Definition: entity.c:2799
entity CreateIntrinsic(string name)
this function does not create an intrinsic function because they must all be created beforehand by th...
Definition: entity.c:1311
entity entity_intrinsic(const char *name)
FI: I do not understand this function name (see next one!).
Definition: entity.c:1292
entity make_label(const char *module_name, const char *local_name)
Definition: entity.c:308
const char * label_local_name(entity e)
END_EOLE.
Definition: entity.c:604
bool expression_call_p(expression e)
Definition: expression.c:415
expression make_call_expression(entity e, list l)
Build an expression that call an function entity with an argument list.
Definition: expression.c:321
expression entity_to_expression(entity e)
if v is a constant, returns a constant call.
Definition: expression.c:165
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
bool user_call_p(call c)
Test if a call is a user call.
Definition: expression.c:4361
expression MakeNullaryCall(entity f)
Creates a call expression to a function with zero arguments.
Definition: expression.c:331
expression MakeUnaryCall(entity f, expression a)
Creates a call expression to a function with one argument.
Definition: expression.c:342
bool empty_extensions_p(extensions es)
Definition: extension.c:50
extensions empty_extensions(void)
extension.c
Definition: extension.c:43
entity make_stderr_variable(void)
If the parser has not (yet) encountered "stderr", a PIPS transformation or instrumentation phase may ...
Definition: variable.c:302
type ultimate_type(type)
Definition: type.c:3466
bool qualifiers_equal_p(list, list)
Definition: type.c:758
bool place_holder_variable_p(entity)
Definition: variable.c:2069
bool basic_equal_p(basic, basic)
Definition: type.c:927
size_t type_depth(type)
Number of steps to access the lowest leave of type t without dereferencing.
Definition: type.c:4880
entity find_label_entity(const char *, const char *)
util.c
Definition: util.c:43
#define value_undefined_p(x)
Definition: ri.h:3017
#define PRAGMA(x)
PRAGMA.
Definition: ri.h:1991
#define loop_body(x)
Definition: ri.h:1644
@ is_basic_string
Definition: ri.h:576
#define value_code_p(x)
Definition: ri.h:3065
#define syntax_reference_p(x)
Definition: ri.h:2728
#define instruction_sequence_p(x)
Definition: ri.h:1512
#define syntax_reference(x)
Definition: ri.h:2730
#define reference_undefined
Definition: ri.h:2302
#define extension_pragma_p(x)
Definition: ri.h:1293
#define instruction_loop_p(x)
Definition: ri.h:1518
#define pragma_string(x)
Definition: ri.h:2033
#define call_function(x)
Definition: ri.h:709
#define extensions_undefined_p(x)
Definition: ri.h:1309
#define reference_variable(x)
Definition: ri.h:2326
#define loop_domain
newgen_language_domain_defined
Definition: ri.h:218
#define value_intrinsic_p(x)
Definition: ri.h:3074
#define reference_undefined_p(x)
Definition: ri.h:2303
#define instruction_multitest_p(x)
Definition: ri.h:1533
#define ENTITY(x)
ENTITY.
Definition: ri.h:2755
#define test_undefined
Definition: ri.h:2808
#define instruction_loop(x)
Definition: ri.h:1520
#define statement_ordering(x)
Definition: ri.h:2454
#define instruction_multitest(x)
Definition: ri.h:1535
#define instruction_goto(x)
Definition: ri.h:1526
#define test_false(x)
Definition: ri.h:2837
#define pragma_string_p(x)
Definition: ri.h:2031
#define entity_storage(x)
Definition: ri.h:2794
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define instruction_undefined_p(x)
Definition: ri.h:1455
#define storage_ram_p(x)
Definition: ri.h:2519
#define instruction_domain
newgen_functional_domain_defined
Definition: ri.h:202
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
#define ram_section(x)
Definition: ri.h:2249
#define basic_undefined_p(x)
Definition: ri.h:557
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define instruction_forloop_p(x)
Definition: ri.h:1536
#define instruction_undefined
Definition: ri.h:1454
#define statement_label(x)
Definition: ri.h:2450
#define extension_pragma(x)
Definition: ri.h:1295
#define EXTENSION(x)
EXTENSION.
Definition: ri.h:1253
#define entity_undefined_p(x)
Definition: ri.h:2762
#define reference_domain
newgen_range_domain_defined
Definition: ri.h:338
#define entity_undefined
Definition: ri.h:2761
#define expression_undefined
Definition: ri.h:1223
@ 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_sequence
Definition: ri.h:1469
@ is_instruction_forloop
Definition: ri.h:1477
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define whileloop_label(x)
Definition: ri.h:3164
#define entity_name(x)
Definition: ri.h:2790
#define test_true(x)
Definition: ri.h:2835
#define sequence_statements(x)
Definition: ri.h:2360
#define reference_indices(x)
Definition: ri.h:2328
#define statement_extensions(x)
Definition: ri.h:2464
#define instruction_sequence(x)
Definition: ri.h:1514
#define instruction_forloop(x)
Definition: ri.h:1538
#define syntax_call(x)
Definition: ri.h:2736
#define loop_label(x)
Definition: ri.h:1646
#define unstructured_exit(x)
Definition: ri.h:3006
#define instruction_unstructured_p(x)
Definition: ri.h:1530
#define instruction_call_p(x)
Definition: ri.h:1527
#define instruction_expression(x)
Definition: ri.h:1541
#define test_condition(x)
Definition: ri.h:2833
#define instruction_whileloop(x)
Definition: ri.h:1523
#define unstructured_entry(x)
Definition: ri.h:3004
#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 statement_comments(x)
Definition: ri.h:2456
#define instruction_whileloop_p(x)
Definition: ri.h:1521
#define persistant_statement_to_int_undefined
Definition: ri.h:1915
#define storage_ram(x)
Definition: ri.h:2521
#define statement_decls_text(x)
Definition: ri.h:2462
#define instruction_call(x)
Definition: ri.h:1529
#define extensions_extension(x)
Definition: ri.h:1330
#define multitest_body(x)
Definition: ri.h:1735
#define instruction_test_p(x)
Definition: ri.h:1515
#define call_arguments(x)
Definition: ri.h:711
#define control_statement(x)
Definition: ri.h:941
#define instruction_test(x)
Definition: ri.h:1517
#define statement_undefined_p(x)
Definition: ri.h:2420
#define entity_type(x)
Definition: ri.h:2792
#define statement_number(x)
Definition: ri.h:2452
#define value_expression_p(x)
Definition: ri.h:3080
#define instruction_goto_p(x)
Definition: ri.h:1524
#define expression_syntax(x)
Definition: ri.h:1247
#define forloop_body(x)
Definition: ri.h:1372
#define value_expression(x)
Definition: ri.h:3082
#define instruction_unstructured(x)
Definition: ri.h:1532
@ is_language_fortran
Definition: ri.h:1566
@ is_language_fortran95
Definition: ri.h:1568
@ is_language_c
Definition: ri.h:1567
#define loop_index(x)
Definition: ri.h:1640
#define statement_undefined
Definition: ri.h:2419
#define instruction_expression_p(x)
Definition: ri.h:1539
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
#define entity_initial(x)
Definition: ri.h:2796
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
s1
Definition: set.c:247
#define ifdebug(n)
Definition: sg.c:47
static size_t current
Definition: string.c:115
static string buffer
Definition: string.c:113
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
structure used by find_statements_with_label_walker
Definition: statement.c:3777
used to pass parameters to find_statements_with_comment_walker
Definition: statement.c:3888
Definition: statement.c:4047
Definition: statement.c:54
instruction MakeSimpleIoInst2(int keyword, expression f, list io_list)
Definition: statement.c:1899