PIPS
unstructured.c
Go to the documentation of this file.
1 /*
2 
3  $Id: unstructured.c 23065 2016-03-02 09:05:50Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of PIPS.
8 
9  PIPS is free software: you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  PIPS is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with PIPS. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 #ifdef HAVE_CONFIG_H
25  #include "pips_config.h"
26 #endif
27  /*
28  * Prettyprint unstructured
29  */
30 
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <string.h>
34 
35 #include "linear.h"
36 
37 #include "genC.h"
38 #include "text.h"
39 #include "text-util.h"
40 #include "ri.h"
41 #include "ri-util.h"
42 #include "prettyprint.h"
43 
44 #include "misc.h"
45 #include "properties.h"
46 
47 static void decorate_trail(entity module, list trail, hash_table labels);
48 static text text_trail(entity module, int margin, list trail, hash_table labels, list * ppdl);
49 static bool control_in_trail_p(list l, control c);
50 static bool appears_first_in_trail(list l, control c1, control c2);
51 static void set_control_to_label(entity m, control c, hash_table h);
52 static string control_to_label_name(control c, hash_table h);
53 
54 text
56  const char* label,
57  int margin,
58  unstructured u,
59  int num,
60  list * ppdl)
61 {
62  text r = make_text(NIL);
64 
65  debug(2, "text_unstructured", "Begin for unstructured %p\n", u);
66 
67  ifdebug(3) {
68  list blocks = NIL;
69  control cexit = unstructured_exit(u) ;
70  control centry = unstructured_control(u) ;
71 
72  fprintf(stderr,"Unstructured %p (%p, %p)\n", u, centry, cexit) ;
73  CONTROL_MAP( n, {
75 
76  /*
77  fprintf(stderr, "\n%*sNode %p (%s)\n--\n", margin, "",
78  (unsigned int) n, control_to_label_name(n, labels)) ;
79  */
80  fprintf(stderr, "\n%*sNode %p (%s)\n--\n", margin, "",
82  ifdebug(9) {
83  list pdl = NIL;
84  print_text(stderr, text_statement(module,margin,st,&pdl));
85  gen_free_list(pdl);
86  }
87  fprintf(stderr, "--\n%*sPreds:", margin, "");
88  MAPL(ps,{
90  fprintf(stderr,"%p (%d,%d), ", CONTROL(CAR(ps)),
92  }, control_predecessors(n));
93  fprintf(stderr, "\n%*sSuccs:", margin, "") ;
94  MAPL(ss,{
96  fprintf(stderr,"%p (%d,%d), ", CONTROL(CAR(ss)),
98  }, control_successors(n));
99  fprintf(stderr, "\n\n") ;
100  }, centry , blocks) ;
102  }
103 
104  if (get_bool_property("PRETTYPRINT_UNSTRUCTURED_AS_A_GRAPH"))
105  {
107  (r, module, label, margin, u, num);
108  }
109  else {
110  list trail = NIL;
111 
112  if(get_bool_property("PRETTYPRINT_UNSTRUCTURED")) {
113  list pbeg = CHAIN_SWORD(NIL, "BEGIN UNSTRUCTURED");
115 
118  }
119 
120  /* build an arbitrary reverse trail of control nodes */
121  trail = unstructured_to_trail(u);
122  debug(3, "text_unstructured", "Trail length: %d\n", gen_length(trail));
123 
124  trail = gen_nreverse(trail);
125 
126  ifdebug(3)
127  dump_trail(trail);
128 
129  /* decorate control nodes with labels when necessary */
130  decorate_trail(module, trail, labels);
131 
132  ifdebug(3)
134 
135  /* generate text with labels and goto's */
136 
137  MERGE_TEXTS(r, text_trail(module, margin, trail, labels, ppdl));
138 
139  if(get_bool_property("PRETTYPRINT_UNSTRUCTURED")) {
140  list pend = CHAIN_SWORD(NIL, "END UNSTRUCTURED");
144  }
145  gen_free_list(trail);
146  }
147 
148  hash_table_free(labels) ;
149 
150  debug(2, "text_unstructured", "End for unstructured %p\n", u);
151 
152  return(r) ;
153 }
154 
155 /* Any heuristics can be used to build the trail, depth or width first,
156  * true or false branch first, lower statement numbering first or not,
157  * sorted by statement numbering (but some statements have no number...).
158  * No simple heuristics seems to be bullet proof.
159  *
160  * The exit node must be last in the trace, or an extra node has to be added
161  * to reach the continuation of the unstructured (see text_trail()).
162  *
163  * For CONS convenience, the list is built in reverse order (and reversed
164  * by the caller).
165  */
166 static list
168 {
169  control succ = control_undefined;
170  int nsucc = 0;
171 
173  !get_bool_property("PRETTYPRINT_CHECK_IO_STATEMENTS")) {
174  /* Do not add this artificial node to the trail, follow the left
175  * successors only
176  */
177  pips_assert("Must be a test statement",
179  debug(3, "build_trail", "Skipping IO check %s",
181  succ = CONTROL(CAR(CDR(control_successors(c))));
182  debug(3, "build_trail", "False Successor: %s",
184  l = build_trail(l, succ);
185  succ = CONTROL(CAR(control_successors(c)));
186  debug(3, "build_trail", "True Successor: %s",
188  l = build_trail(l, succ);
189  }
190  else {
191 
192  nsucc = gen_length(control_successors(c));
193 
194  debug(3, "build_trail", "for %s with %d successors\n",
196  nsucc);
197  ifdebug(3) {
198  int i = 1;
199  MAPL(cs, {
201  debug(3, "build_trail", "Successor %d: %s",
202  i++, statement_identification(ss));
203  }, control_successors(c));
204  }
205 
206  /* Add c to the trail if not already in */
207  if(!control_in_trail_p(l, c)) {
208  debug(3, "build_trail", "Add to trail %s",
210  l = CONS(CONTROL,c,l);
211  switch(nsucc) {
212  case 0:
213  break;
214  case 1:
215  succ = CONTROL(CAR(control_successors(c)));
216  l = build_trail(l, succ);
217  break;
218  case 2:
219  /* Follow the false branch in depth first, assuming that IF GOTO's
220  * mainly handle exceptions */
221  succ = CONTROL(CAR(CDR(control_successors(c))));
222  l = build_trail(l, succ);
223  succ = CONTROL(CAR(control_successors(c)));
224  l = build_trail(l, succ);
225  break;
226  default:
227  pips_internal_error("Too many successors (%d) for a control node",
228  nsucc);
229  }
230  }
231  else {
232  debug(3, "build_trail", "Already in trail %s",
234  }
235  }
236  return l;
237 }
238 
239 list
241 {
242  list trail = NIL;
243  control centry = unstructured_control(u) ;
244  control cexit = unstructured_exit(u) ;
245 
246  trail = build_trail(trail, centry);
247 
248  /* The exit node *must* be first (i.e. last) to reach the continuation
249  * of the unstructured, or never reached (e.g. because the program loops
250  * forever or stops in the unstructured).
251  */
252  if(control_in_trail_p(trail, cexit)) {
253  if(cexit!=CONTROL(CAR(trail))) {
254  gen_remove(&trail, cexit);
255  trail = CONS(CONTROL, cexit, trail);
256  }
257  }
258 
259  return trail;
260 }
261 
262 void
264 {
265  if(ENDP(trail)) {
266  fprintf(stderr, "[dump_trail] trail is empty\n");
267  }
268  else {
269  fprintf(stderr, "[dump_trail] begin\n");
270  MAPL(cc, {
272  fprintf(stderr, "[dump_trail] %s", statement_identification(s));
273  }, trail);
274  fprintf(stderr, "[dump_trail] end\n");
275  }
276 }
277 
278 /* OK, a hash table could be used, as Pierre used too... but the order
279  * is lost. You need both ordered and direct accesses. Easy to add later if too
280  * slow.
281  */
282 static bool
284 {
285  bool found = gen_find_eq(c, l) != gen_chunk_undefined;
286  return found;
287 }
288 
289 static void
291 {
292  list cc = NIL;
293 
294  pips_assert("trail cannot be empty", !ENDP(trail));
295 
296  for(cc=trail; !ENDP(cc); POP(cc)) {
297  control c = CONTROL(CAR(cc));
298  int nsucc = gen_length(control_successors(c));
299 
300  debug(3, "decorate_trail", "Processing statement %s with %d successors\n",
302 
303  switch(nsucc) {
304  case 0:
305  /* No need for a label, it must be the exit node... Should be asserted
306  * The exit node may have two successors
307  */
308  break;
309  case 1: {
311 
313  !get_bool_property("PRETTYPRINT_CHECK_IO_STATEMENTS")) {
314  /* The real successor is the false successor of the IO check */
315  succ = CONTROL(CAR(CDR(control_successors(succ))));
317  !get_bool_property("PRETTYPRINT_CHECK_IO_STATEMENTS")) {
318  /* The real successor is the false successor of the IO check */
319  succ = CONTROL(CAR(CDR(control_successors(succ))));
320  }
321  pips_assert("The successor is not a check io statement",
323  }
324 
325  /* If the statement "really" has a continuation (e.g. not a STOP
326  * or a RETURN)
327  */
328  /* if(statement_does_return(control_statement(c)) &&
329  !(check_io_statement_p(control_statement(succ)) &&
330  !get_bool_property("PRETTYPRINT_CHECK_IO_STATEMENTS"))) { */
332  if(!ENDP(CDR(cc))) {
333  control tsucc = CONTROL(CAR(CDR(cc)));
334  if(tsucc==succ) {
335  /* the control successor is the textual successor */
336  break;
337  }
338  }
339  /* A label must be associated with the control successor */
340  pips_assert("Successor must be in trail",
341  control_in_trail_p(trail, succ));
342  set_control_to_label(module, succ, labels);
343  }
344  break;
345  }
346  case 2: {
347  control succ1 = CONTROL(CAR(control_successors(c)));
348  control succ2 = CONTROL(CAR(CDR(control_successors(c))));
349 
350  debug(3, "decorate_trail", "Successor 1 %s",
352  debug(3, "decorate_trail", "Successor 2 %s",
354 
355  /* Is there a textual successor? */
356  if(!ENDP(CDR(cc))) {
357  control tsucc = CONTROL(CAR(CDR(cc)));
358  if(tsucc==succ1) {
359  if(tsucc==succ2) {
360  /* This may happen after restructuring */
361  ;
362  }
363  else {
364  /* succ2 must be labelled */
365  pips_assert("Successor 2 must be in trail",
366  control_in_trail_p(trail, succ2));
367  set_control_to_label(module, succ2, labels);
368  }
369  }
370  else {
371  if(tsucc==succ2) {
372  /* succ1 must be labelled */
373  pips_assert("Successor 1 must be in trail",
374  control_in_trail_p(trail, succ1));
375  set_control_to_label(module, succ1, labels);
376  }
377  else {
378  /* Both successors must be labelled */
379  pips_assert("Successor 1 must be in trail",
380  control_in_trail_p(trail, succ1));
381  set_control_to_label(module, succ1, labels);
382  pips_assert("Successor 2 must be in trail",
383  control_in_trail_p(trail, succ2));
384  set_control_to_label(module, succ2, labels);
385  }
386  }
387  }
388  else {
389  /* Both successors must be textual predecessors */
390  pips_assert("succ1 before c", appears_first_in_trail(trail, succ1, c));
391  pips_assert("succ2 before c", appears_first_in_trail(trail, succ2, c));
392  set_control_to_label(module, succ1, labels);
393  set_control_to_label(module, succ2, labels);
394  }
395  break;
396  }
397  default:
398  pips_internal_error("Too many successors for a control node");
399  }
400  }
401 }
402 
403 /* returns true if c1 is encountered before c2 in trail, or if c1 == c2
404  * is encountered in trail, false is c2 is encountered first and c2 != c1,
405  * core dumps otherwise, if neither c1 nor c2 is in trail
406  */
407 static bool
409 {
410  bool first = false;
412 
413  MAPL(cc, {
414  c = CONTROL(CAR(cc));
415 
416  if(c==c1) {
417  first = true;
418  break;
419  }
420  else if(c==c2) {
421  first = false;
422  break;
423  }
424  }, trail);
425  pips_assert("At least one control should appear in trail", c==c1 || c==c2);
426  return first;
427 }
428 
429 
430 /* set_control_to_label allocates label for the control
431  * node c in the module m. h maps controls to label names. Computes a new
432  * label name if necessary.
433  *
434  * There is no guarantee that a label generated here appears eventually
435  * in the text produced.
436  *
437  * There is no guarantee that a label generated here is jumped at.
438  */
439 
440 static void
442 {
443  char* l;
444  statement st = control_statement(c) ;
445 
446  if ((l = hash_get(h, (char *) c)) == HASH_UNDEFINED_VALUE) {
447  const char* label = entity_name( statement_to_label( st )) ;
448  if(empty_global_label_p( label )) {
449  char * lname = new_label_local_name(m);
450  const char * module_name =
451  entity_undefined_p(m) ?
454 
456  free(lname);
457  }
458  else {
459  l=strdup(label);
460  }
461 
462  /* memory leak in debug code: statement_identification(). */
463  pips_debug(3, "Associates label %s to stmt %s\n",
464  l, statement_identification(st));
465  hash_put(h, (char *) c, l) ;
466  }
467  else {
468  debug(3, "set_control_to_label", "Retrieves label %s for stmt %s\n",
469  l, statement_identification(st));
470  }
471 
472  pips_assert("set_control_to_label", strcmp(local_name(l), LABEL_PREFIX) != 0) ;
473  pips_assert("set_control_to_label", strcmp(local_name(l), "") != 0) ;
474  pips_assert("set_control_to_label", strcmp(local_name(l), "=") != 0) ;
475 
476  return;
477 }
478 
479 static string
481 {
482  char* l;
483  statement st = control_statement(c) ;
484 
485  if ((l = hash_get(h, (char *) c)) == HASH_UNDEFINED_VALUE) {
486  debug(3, "control_to_label_name", "Retrieves no label for stmt %s\n",
488  l = string_undefined;
489  }
490  else {
491  debug(3, "control_to_label_name", "Retrieves label %s for stmt %s\n",
492  l, statement_identification(st));
493  l = strdup(local_name(l)+sizeof(LABEL_PREFIX)-1);
494  }
495 
496  return l;
497 }
498 
499 void
501 {
502  int i = 0;
503 
504  fprintf(stderr,"[dump_control_to_label_name] Begin\n");
505  HASH_MAP(c,l,{
506  fprintf(stderr, "Label %s -> %s", (char *) l,
508  i++;
509  }, h);
510  fprintf(stderr,"[dump_control_to_label_name] %d labels, end\n", i);
511 }
512 
513 static text text_trail(entity module, int margin, list trail, hash_table labels, list * ppdl) {
514  list cc = NIL;
515  text r = make_text(NIL);
516 
517  pips_assert("trail cannot be empty", !ENDP(trail));
518 
519  for (cc = trail; !ENDP(cc); POP(cc)) {
520  control c = CONTROL(CAR(cc));
521  string l = string_undefined;
522  int nsucc = gen_length(control_successors(c));
524 
525  pips_debug(3, "Processing statement %s", statement_identification(st));
526 
527  /* Is a label needed? */
528  if ((l = control_to_label_name(c, labels)) != string_undefined) {
530  != 0) {
531  list pc = NIL;
532  switch (get_prettyprint_language_tag()) {
533  case is_language_fortran:
535  pc = CHAIN_SWORD(pc, "CONTINUE");
536  break;
537  case is_language_c:
538  pc = CHAIN_SWORD(pc, ";");
539  break;
540  default:
541  pips_internal_error("Language unknown !");
542  break;
543  }
545  make_unformatted(NULL, 0, margin, pc));
547  ADD_SENTENCE_TO_TEXT(r, s);
548  pips_debug(3,
549  "Label %s generated for stmt %s\n",
550  l,
552  }
553  }
554 
555  /* Perform the very same tests as in decorate_trail()
556  * The successor may have a label but not need a GOTO to be reached.
557  */
558 
559  switch(nsucc) {
560  case 0: {
561  /* Build the statement text with enclosing braces if necessary in
562  C and skip parasitic continues */
563  MERGE_TEXTS(r, text_statement_enclosed(module, margin, st, one_liner_p(st), true, ppdl));
564  }
565  break;
566  case 1: {
568 
570  && !get_bool_property("PRETTYPRINT_CHECK_IO_STATEMENTS")) {
571  /* The real successor is the false successor of the IO check */
572  succ = CONTROL(CAR(CDR(control_successors(succ))));
574  && !get_bool_property("PRETTYPRINT_CHECK_IO_STATEMENTS")) {
575  /* The real successor is the false successor of the IO check */
576  succ = CONTROL(CAR(CDR(control_successors(succ))));
577  }
578  pips_assert("The successor is not a check io statement",
580  }
581 
582  /* Build the statement text with enclosing braces if necessary in
583  C and skip parasitic continues */
584  list pdl = NIL;
585  MERGE_TEXTS(r, text_statement_enclosed(module, margin, st, one_liner_p(st), true, &pdl));
586  gen_free_list(pdl);
587 
588  /* If the statement "really" has a continuation (e.g. not a STOP
589  * or a RETURN)
590  */
591  /* if(statement_does_return(st) &&
592  !(check_io_statement_p(control_statement(succ)) &&
593  !get_bool_property("PRETTYPRINT_CHECK_IO_STATEMENTS")) ) { */
594  if (statement_does_return(st)) {
595  if (!ENDP(CDR(cc))) {
596  control tsucc = CONTROL(CAR(CDR(cc)));
597  if (tsucc == succ) {
598  /* the control successor is the textual successor */
599  break;
600  }
601  }
602  /* A GOTO must be generated to reach the control successor */
603  l = control_to_label_name(succ, labels);
604  pips_assert("Must be labelled", l!= string_undefined);
606  margin, l, 0));
607  }
608  break;
609  }
610  case 2: {
611  control succ1 = CONTROL(CAR(control_successors(c)));
612  control succ2 = CONTROL(CAR(CDR(control_successors(c))));
614  test t = test_undefined;
616  list pc = NIL;
618  string comments = statement_comments(st);
619  text r1 = make_text(NIL);
620  bool no_endif = false;
621 
622  pips_assert("must be a test", instruction_test_p(i));
623 
624  MERGE_TEXTS(r, init_text_statement(module, margin, st));
625  if (!string_undefined_p(comments)) {
626  switch(get_prettyprint_language_tag()) {
627  case is_language_fortran:
630  strdup(comments)));
631  break;
632  case is_language_c: {
633  text ct = C_comment_to_text(margin, comments);
634  MERGE_TEXTS(r, ct);
635  }
636  break;
637  default:
638  pips_internal_error("Language unknown !");
639  break;
640  }
641  }
642 
643  switch (get_prettyprint_language_tag()) {
644  case is_language_fortran:
646  pc = CHAIN_SWORD(NIL, "IF (");
647  break;
648  case is_language_c:
649  pc = CHAIN_SWORD(NIL, "if (");
650  break;
651  default:
652  pips_internal_error("Language unknown !");
653  break;
654  }
655  t = instruction_test(i);
656  pc = gen_nconc(pc, words_expression(test_condition(t), ppdl));
657 
658  /* Is there a textual successor? */
659  if (!ENDP(CDR(cc))) {
660  control tsucc = CONTROL(CAR(CDR(cc)));
661  if (tsucc == succ1) {
662  if (tsucc == succ2) {
663  /* This may happen after restructuring */
664  ;
665  } else {
666  /* succ2 must be reached by GOTO */
667  l = control_to_label_name(succ2, labels);
668  pips_assert("Must be labelled", l!= string_undefined);
669  switch (get_prettyprint_language_tag()) {
670  case is_language_fortran:
673  MAKE_ONE_WORD_SENTENCE(margin,"ELSE"));
674  break;
675  case is_language_c:
678  "else {" ));
679  break;
680  default:
681  pips_internal_error("Language unknown !");
682  break;
683  }
685  margin+INDENTATION,
686  l, 0));
687  }
688  } else {
689  if (tsucc == succ2) {
690  /* succ1 must be reached by GOTO */
691  l = control_to_label_name(succ1, labels);
692  pips_assert("Must be labelled", l!= string_undefined);
693  no_endif = true;
694  } else {
695  /* Both successors must be labelled */
696  l = control_to_label_name(succ1, labels);
697  pips_assert("Must be labelled", l!= string_undefined);
699  margin+INDENTATION,
700  l, 0));
701  switch (get_prettyprint_language_tag()) {
702  case is_language_fortran:
705  MAKE_ONE_WORD_SENTENCE(margin,"ELSE"));
706  break;
707  case is_language_c:
710  "else {" ));
711  break;
712  default:
713  pips_internal_error("Language unknown !");
714  break;
715  }
716  l = control_to_label_name(succ2, labels);
717  pips_assert("Must be labelled", l!= string_undefined);
719  margin+INDENTATION,
720  l, 0));
721  }
722  }
723  } else {
724  /* Both successors must be textual predecessors */
725  pips_assert("succ1 before c", appears_first_in_trail(trail, succ1, c));
726  pips_assert("succ1 before c", appears_first_in_trail(trail, succ2, c));
727  l = control_to_label_name(succ1, labels);
728  pips_assert("Must be labelled", l!= string_undefined);
730  margin+INDENTATION,
731  l, 0));
732  switch (get_prettyprint_language_tag()) {
733  case is_language_fortran:
735  ADD_SENTENCE_TO_TEXT(r1, MAKE_ONE_WORD_SENTENCE(margin,"ELSE"));
736  break;
737  case is_language_c:
739  ADD_SENTENCE_TO_TEXT(r1, MAKE_ONE_WORD_SENTENCE(margin,"else {" ));
740  break;
741  default:
742  pips_internal_error("Language unknown !");
743  break;
744  }
745  l = control_to_label_name(succ2, labels);
746  pips_assert("Must be labelled", l!= string_undefined);
748  margin+INDENTATION,
749  l, 0));
750  }
751 
752  if (no_endif) {
753  pc = CHAIN_SWORD(pc, ") ");
754  pc = gen_nconc(pc, words_goto_label(l));
755  } else {
756  switch (get_prettyprint_language_tag()) {
757  case is_language_fortran:
759  pc = CHAIN_SWORD(pc, ") THEN");
760  break;
761  case is_language_c:
762  pc = CHAIN_SWORD(pc, ") {");
763  break;
764  default:
765  pips_internal_error("Language unknown !");
766  break;
767  }
768  }
769  u = make_unformatted(NULL, statement_number(st), margin, pc);
770 
772  /*
773  string ln = control_to_label_name(c, labels);
774  if(string_undefined_p(ln)) {
775  entity lab = statement_label(st);
776  print_statement(st);
777  pips_assert("c must have been encountered before", !string_undefined_p(ln));
778  }
779  unformatted_label(u) = strdup(ln);
780  */
782  }
783 
785  ADD_SENTENCE_TO_TEXT(r, s);
786  MERGE_TEXTS(r, r1);
787  if (!no_endif) {
788  switch (get_prettyprint_language_tag()) {
789  case is_language_fortran:
791  ADD_SENTENCE_TO_TEXT(r, MAKE_ONE_WORD_SENTENCE(margin, "ENDIF"));
792  break;
793  case is_language_c:
795  break;
796  default:
797  pips_internal_error("Language unknown !");
798  break;
799  }
800  }
801  break;
802  }
803  default:
804  pips_internal_error("Too many successors for a control node");
805  }
806  }
807 
808  return r;
809 }
unformatted make_unformatted(string a1, intptr_t a2, intptr_t a3, list a4)
Definition: text.c:149
sentence make_sentence(enum sentence_utype tag, void *val)
Definition: text.c:59
text make_text(list a)
Definition: text.c:107
static int num
Definition: bourdoncle.c:137
static list blocks
lisp of loops
bool empty_global_label_p(const char *gln)
Definition: entity_names.c:264
const char * local_name(const char *s)
Does not take care of block scopes and returns a pointer.
Definition: entity_names.c:221
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
#define gen_chunk_undefined
Definition: genC.h:74
void free(void *)
#define CONTROL_MAP(ctl, code, c, list)
Macro to walk through all the controls reachable from a given control node of an unstructured.
#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
void gen_remove(list *cpp, const void *o)
remove all occurences of item o from list *cpp, which is thus modified.
Definition: list.c:685
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
size_t gen_length(const list l)
Definition: list.c:150
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
void * gen_find_eq(const void *item, const list seq)
Definition: list.c:422
#define MAPL(_map_list_cp, _code, _l)
Apply some code on the addresses of all the elements of a list.
Definition: newgen_list.h:203
bool check_io_statement_p(statement)
Definition: statement.c:528
entity statement_to_label(statement)
See if statement s is labelled and can be reached by a GO TO.
Definition: statement.c:2090
string statement_identification(statement)
Like external_statement_identification(), but with internal information, the hexadecimal address of t...
Definition: statement.c:1700
bool statement_does_return(statement)
Returns false is no syntactic control path exits s (i.e.
Definition: statement.c:2195
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_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
enum language_utype get_prettyprint_language_tag()
Definition: language.c:67
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#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
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 MODULE_SEP_STRING
Definition: naming-local.h:30
#define HASH_MAP(k, v, code, ht)
Definition: newgen_hash.h:60
@ hash_pointer
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 string_undefined
Definition: newgen_types.h:40
#define string_undefined_p(s)
Definition: newgen_types.h:41
static char * module
Definition: pips.c:74
string get_comment_sentinel()
Start a single line comment.
Definition: misc.c:154
list words_goto_label(const char *tlabel)
This function is useful only for parsed codes since gotos are removed by the controlizer.
Definition: misc.c:1917
bool one_liner_p(statement s)
True is statement "s" can be printed out without enclosing braces when it is the true branch of a tes...
Definition: misc.c:301
list words_expression(expression obj, list *ppdl)
This one is exported.
Definition: misc.c:2611
text init_text_statement(entity module, int margin, statement obj)
exported for unstructured.c
Definition: misc.c:3462
text C_comment_to_text(int margin, string comment)
Special handling for C comments with each line indented according to the context.
Definition: misc.c:4270
sentence sentence_goto_label(entity __attribute__((unused)) module, const char *label, int margin, const char *tlabel, int n)
exported for unstructured.c
Definition: misc.c:2784
static list build_trail(list l, control c)
Any heuristics can be used to build the trail, depth or width first, true or false branch first,...
Definition: unstructured.c:167
static text text_trail(entity module, int margin, list trail, hash_table labels, list *ppdl)
Definition: unstructured.c:513
static bool appears_first_in_trail(list l, control c1, control c2)
returns true if c1 is encountered before c2 in trail, or if c1 == c2 is encountered in trail,...
Definition: unstructured.c:408
void dump_trail(list trail)
Definition: unstructured.c:263
static bool control_in_trail_p(list l, control c)
OK, a hash table could be used, as Pierre used too...
Definition: unstructured.c:283
void dump_control_to_label_name(hash_table h)
Definition: unstructured.c:500
text text_unstructured(entity module, const char *label, int margin, unstructured u, int num, list *ppdl)
unstructured.c
Definition: unstructured.c:55
static void set_control_to_label(entity m, control c, hash_table h)
set_control_to_label allocates label for the control node c in the module m.
Definition: unstructured.c:441
static string control_to_label_name(control c, hash_table h)
Definition: unstructured.c:480
list unstructured_to_trail(unstructured u)
Definition: unstructured.c:240
static void decorate_trail(entity module, list trail, hash_table labels)
Definition: unstructured.c:290
text text_statement(entity, int, statement, list *)
void output_a_graph_view_of_the_unstructured(text, entity, const char *, int, unstructured, int)
text text_statement_enclosed(entity, int, statement, bool, bool, list *)
#define ORDERING_NUMBER(o)
#define ORDERING_STATEMENT(o)
#define unstructured_control
After the modification in Newgen: unstructured = entry:control x exit:control we have create a macro ...
#define GENERATED_LABEL_MODULE_NAME
#define INDENTATION
char * new_label_local_name(entity module)
Definition: entity.c:326
const char * module_local_name(entity e)
Returns the module local user name.
Definition: entity.c:582
const char * label_local_name(entity e)
END_EOLE.
Definition: entity.c:604
#define control_undefined
Definition: ri.h:916
#define control_predecessors(x)
Definition: ri.h:943
#define test_undefined
Definition: ri.h:2808
#define statement_ordering(x)
Definition: ri.h:2454
#define CONTROL(x)
CONTROL.
Definition: ri.h:910
#define statement_label(x)
Definition: ri.h:2450
#define entity_undefined_p(x)
Definition: ri.h:2762
#define entity_name(x)
Definition: ri.h:2790
#define control_successors(x)
Definition: ri.h:945
#define unstructured_exit(x)
Definition: ri.h:3006
#define test_condition(x)
Definition: ri.h:2833
#define statement_instruction(x)
Definition: ri.h:2458
#define statement_comments(x)
Definition: ri.h:2456
#define instruction_test_p(x)
Definition: ri.h:1515
#define control_statement(x)
Definition: ri.h:941
#define instruction_test(x)
Definition: ri.h:1517
#define statement_number(x)
Definition: ri.h:2452
@ is_language_fortran
Definition: ri.h:1566
@ is_language_fortran95
Definition: ri.h:1568
@ is_language_c
Definition: ri.h:1567
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
char * strdup()
#define ifdebug(n)
Definition: sg.c:47
static int lname(char *s, int look_for_entry)
check for keywords for subprograms return 0 if comment card, 1 if found name and put in arg string.
Definition: split_file.c:283
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
#define CHAIN_SWORD(l, s)
#define MERGE_TEXTS(r, t)
#define MAKE_ONE_WORD_SENTENCE(m, s)
#define ADD_SENTENCE_TO_TEXT(t, p)
void print_text(FILE *fd, text t)
Definition: print.c:195
#define sentence_undefined
Definition: text.h:42
#define unformatted_undefined
Definition: text.h:123
#define sentence_unformatted(x)
Definition: text.h:81
#define unformatted_label(x)
Definition: text.h:149
@ is_sentence_formatted
Definition: text.h:57
@ is_sentence_unformatted
Definition: text.h:58