PIPS
unstructured.c File Reference
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "linear.h"
#include "genC.h"
#include "text.h"
#include "text-util.h"
#include "ri.h"
#include "ri-util.h"
#include "prettyprint.h"
#include "misc.h"
#include "properties.h"
+ Include dependency graph for unstructured.c:

Go to the source code of this file.

Functions

static void decorate_trail (entity module, list trail, hash_table labels)
 
static text text_trail (entity module, int margin, list trail, hash_table labels, list *ppdl)
 
static bool control_in_trail_p (list l, control c)
 OK, a hash table could be used, as Pierre used too... More...
 
static bool appears_first_in_trail (list trail, control c1, control c2)
 returns true if c1 is encountered before c2 in trail, or if c1 == c2 is encountered in trail, false is c2 is encountered first and c2 != c1, core dumps otherwise, if neither c1 nor c2 is in trail More...
 
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. More...
 
static string control_to_label_name (control c, hash_table h)
 
text text_unstructured (entity module, const char *label, int margin, unstructured u, int num, list *ppdl)
 unstructured.c More...
 
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, lower statement numbering first or not, sorted by statement numbering (but some statements have no number...). More...
 
list unstructured_to_trail (unstructured u)
 
void dump_trail (list trail)
 
void dump_control_to_label_name (hash_table h)
 

Function Documentation

◆ appears_first_in_trail()

static bool appears_first_in_trail ( list  l,
control  c1,
control  c2 
)
static

returns true if c1 is encountered before c2 in trail, or if c1 == c2 is encountered in trail, false is c2 is encountered first and c2 != c1, core dumps otherwise, if neither c1 nor c2 is in trail

Definition at line 408 of file unstructured.c.

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 }
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#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 pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define control_undefined
Definition: ri.h:916
#define CONTROL(x)
CONTROL.
Definition: ri.h:910

References CAR, CONTROL, control_undefined, MAPL, and pips_assert.

Referenced by decorate_trail(), and text_trail().

+ Here is the caller graph for this function:

◆ build_trail()

static list build_trail ( list  l,
control  c 
)
static

Any heuristics can be used to build the trail, depth or width first, true or false branch first, lower statement numbering first or not, sorted by statement numbering (but some statements have no number...).

No simple heuristics seems to be bullet proof.

The exit node must be last in the trace, or an extra node has to be added to reach the continuation of the unstructured (see text_trail()).

For CONS convenience, the list is built in reverse order (and reversed by the caller).

Do not add this artificial node to the trail, follow the left successors only

Add c to the trail if not already in

Follow the false branch in depth first, assuming that IF GOTO's mainly handle exceptions

Definition at line 167 of file unstructured.c.

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 }
bool get_bool_property(const string)
FC 2015-07-20: yuk, moved out to prevent an include cycle dependency include "properties....
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
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
bool check_io_statement_p(statement)
Definition: statement.c:528
string statement_identification(statement)
Like external_statement_identification(), but with internal information, the hexadecimal address of t...
Definition: statement.c:1700
#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
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 bool control_in_trail_p(list l, control c)
OK, a hash table could be used, as Pierre used too...
Definition: unstructured.c:283
#define control_successors(x)
Definition: ri.h:945
#define statement_instruction(x)
Definition: ri.h:2458
#define instruction_test_p(x)
Definition: ri.h:1515
#define control_statement(x)
Definition: ri.h:941
#define ifdebug(n)
Definition: sg.c:47

References CAR, CDR, check_io_statement_p(), CONS, CONTROL, control_in_trail_p(), control_statement, control_successors, control_undefined, debug(), gen_length(), get_bool_property(), ifdebug, instruction_test_p, MAPL, pips_assert, pips_internal_error, statement_identification(), and statement_instruction.

Referenced by unstructured_to_trail().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ control_in_trail_p()

static bool control_in_trail_p ( list  l,
control  c 
)
static

OK, a hash table could be used, as Pierre used too...

but the order is lost. You need both ordered and direct accesses. Easy to add later if too slow.

Definition at line 283 of file unstructured.c.

284 {
285  bool found = gen_find_eq(c, l) != gen_chunk_undefined;
286  return found;
287 }
#define gen_chunk_undefined
Definition: genC.h:74
void * gen_find_eq(const void *item, const list seq)
Definition: list.c:422

References gen_chunk_undefined, and gen_find_eq().

Referenced by build_trail(), decorate_trail(), and unstructured_to_trail().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ control_to_label_name()

static string control_to_label_name ( control  c,
hash_table  h 
)
static

Definition at line 480 of file unstructured.c.

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 }
const char * local_name(const char *s)
Does not take care of block scopes and returns a pointer.
Definition: entity_names.c:221
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
#define LABEL_PREFIX
Definition: naming-local.h:31
#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
char * strdup()

References control_statement, debug(), hash_get(), HASH_UNDEFINED_VALUE, LABEL_PREFIX, local_name(), statement_identification(), strdup(), and string_undefined.

Referenced by text_trail().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ decorate_trail()

static void decorate_trail ( entity  module,
list  trail,
hash_table  labels 
)
static

No need for a label, it must be the exit node... Should be asserted The exit node may have two successors

The real successor is the false successor of the IO check

The real successor is the false successor of the IO check

If the statement "really" has a continuation (e.g. not a STOP or a RETURN)

if(statement_does_return(control_statement(c)) && !(check_io_statement_p(control_statement(succ)) && !get_bool_property("PRETTYPRINT_CHECK_IO_STATEMENTS"))) {

the control successor is the textual successor

A label must be associated with the control successor

Is there a textual successor?

This may happen after restructuring

succ2 must be labelled

succ1 must be labelled

Both successors must be labelled

Both successors must be textual predecessors

Definition at line 290 of file unstructured.c.

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 }
#define ENDP(l)
Test if a list is empty.
Definition: newgen_list.h:66
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
bool statement_does_return(statement)
Returns false is no syntactic control path exits s (i.e.
Definition: statement.c:2195
static char * module
Definition: pips.c:74
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
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
The structure used to build lists in NewGen.
Definition: newgen_list.h:41

References appears_first_in_trail(), CAR, CDR, check_io_statement_p(), CONTROL, control_in_trail_p(), control_statement, control_successors, debug(), ENDP, gen_length(), get_bool_property(), module, NIL, pips_assert, pips_internal_error, POP, set_control_to_label(), statement_does_return(), and statement_identification().

Referenced by text_unstructured().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dump_control_to_label_name()

void dump_control_to_label_name ( hash_table  h)

Definition at line 500 of file unstructured.c.

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 }
#define HASH_MAP(k, v, code, ht)
Definition: newgen_hash.h:60
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...

References control_statement, fprintf(), HASH_MAP, and statement_identification().

Referenced by text_unstructured().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dump_trail()

void dump_trail ( list  trail)
Parameters
trailrail

Definition at line 263 of file unstructured.c.

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 }

References CAR, CONTROL, control_statement, ENDP, fprintf(), MAPL, and statement_identification().

Referenced by c_unstructured(), and text_unstructured().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ set_control_to_label()

static void set_control_to_label ( entity  m,
control  c,
hash_table  h 
)
static

set_control_to_label allocates label for the control node c in the module m.

h maps controls to label names. Computes a new label name if necessary.

There is no guarantee that a label generated here appears eventually in the text produced.

There is no guarantee that a label generated here is jumped at.

memory leak in debug code: statement_identification().

Definition at line 441 of file unstructured.c.

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 }
bool empty_global_label_p(const char *gln)
Definition: entity_names.c:264
const char * module_name(const char *s)
Return the module part of an entity name.
Definition: entity_names.c:296
void free(void *)
entity statement_to_label(statement)
See if statement s is labelled and can be reached by a GO TO.
Definition: statement.c:2090
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
#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 MODULE_SEP_STRING
Definition: naming-local.h:30
#define GENERATED_LABEL_MODULE_NAME
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
#define entity_undefined_p(x)
Definition: ri.h:2762
#define entity_name(x)
Definition: ri.h:2790
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

References asprintf, control_statement, debug(), empty_global_label_p(), entity_name, entity_undefined_p, free(), GENERATED_LABEL_MODULE_NAME, hash_get(), hash_put(), HASH_UNDEFINED_VALUE, LABEL_PREFIX, lname(), local_name(), module_local_name(), module_name(), MODULE_SEP_STRING, new_label_local_name(), pips_assert, pips_debug, statement_identification(), statement_to_label(), and strdup().

Referenced by decorate_trail().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ text_trail()

static text text_trail ( entity  module,
int  margin,
list  trail,
hash_table  labels,
list ppdl 
)
static

Is a label needed?

Perform the very same tests as in decorate_trail() The successor may have a label but not need a GOTO to be reached.

Build the statement text with enclosing braces if necessary in C and skip parasitic continues

The real successor is the false successor of the IO check

The real successor is the false successor of the IO check

Build the statement text with enclosing braces if necessary in C and skip parasitic continues

If the statement "really" has a continuation (e.g. not a STOP or a RETURN)

if(statement_does_return(st) && !(check_io_statement_p(control_statement(succ)) && !get_bool_property("PRETTYPRINT_CHECK_IO_STATEMENTS")) ) {

the control successor is the textual successor

A GOTO must be generated to reach the control successor

Is there a textual successor?

This may happen after restructuring

succ2 must be reached by GOTO

succ1 must be reached by GOTO

Both successors must be labelled

Both successors must be textual predecessors

Definition at line 513 of file unstructured.c.

513  {
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
list gen_nconc(list cp1, list cp2)
physically concatenates CP1 and CP2 but do not duplicates the elements
Definition: list.c:344
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
enum language_utype get_prettyprint_language_tag()
Definition: language.c:67
#define string_undefined_p(s)
Definition: newgen_types.h:41
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 string control_to_label_name(control c, hash_table h)
Definition: unstructured.c:480
text text_statement_enclosed(entity, int, statement, bool, bool, list *)
#define INDENTATION
const char * label_local_name(entity e)
END_EOLE.
Definition: entity.c:604
#define test_undefined
Definition: ri.h:2808
#define statement_label(x)
Definition: ri.h:2450
#define test_condition(x)
Definition: ri.h:2833
#define statement_comments(x)
Definition: ri.h:2456
#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
#define CHAIN_SWORD(l, s)
#define MERGE_TEXTS(r, t)
#define MAKE_ONE_WORD_SENTENCE(m, s)
#define ADD_SENTENCE_TO_TEXT(t, p)
#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

References ADD_SENTENCE_TO_TEXT, appears_first_in_trail(), C_comment_to_text(), CAR, CDR, CHAIN_SWORD, check_io_statement_p(), CONTROL, control_statement, control_successors, control_to_label_name(), empty_global_label_p(), ENDP, entity_name, gen_free_list(), gen_length(), gen_nconc(), get_bool_property(), get_prettyprint_language_tag(), INDENTATION, init_text_statement(), instruction_test, instruction_test_p, is_language_c, is_language_fortran, is_language_fortran95, is_sentence_formatted, is_sentence_unformatted, label_local_name(), MAKE_ONE_WORD_SENTENCE, make_sentence(), make_text(), make_unformatted(), MERGE_TEXTS, module, NIL, one_liner_p(), pips_assert, pips_debug, pips_internal_error, POP, sentence_goto_label(), sentence_undefined, sentence_unformatted, statement_comments, statement_does_return(), statement_identification(), statement_instruction, statement_label, statement_number, statement_to_label(), strdup(), string_undefined, string_undefined_p, test_condition, test_undefined, text_statement_enclosed(), unformatted_label, unformatted_undefined, words_expression(), and words_goto_label().

Referenced by text_unstructured().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ text_unstructured()

text text_unstructured ( entity  module,
const char *  label,
int  margin,
unstructured  u,
int  num,
list ppdl 
)

unstructured.c

build an arbitrary reverse trail of control nodes

decorate control nodes with labels when necessary

generate text with labels and goto's

Parameters
moduleodule
labelabel
marginargin
numum
ppdlpdl

Definition at line 55 of file unstructured.c.

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 }
static int num
Definition: bourdoncle.c:137
static list blocks
lisp of loops
if(!(yy_init))
Definition: genread_lex.c:1029
#define CONTROL_MAP(ctl, code, c, list)
Macro to walk through all the controls reachable from a given control node of an unstructured.
list gen_nreverse(list cp)
reverse a list in place
Definition: list.c:304
hash_table hash_table_make(hash_key_type key_type, size_t size)
Definition: hash.c:294
void hash_table_free(hash_table htp)
this function deletes a hash table that is no longer useful.
Definition: hash.c:327
@ hash_pointer
Definition: newgen_hash.h:32
string get_comment_sentinel()
Start a single line comment.
Definition: misc.c:154
static text text_trail(entity module, int margin, list trail, hash_table labels, list *ppdl)
Definition: unstructured.c:513
void dump_trail(list trail)
Definition: unstructured.c:263
void dump_control_to_label_name(hash_table h)
Definition: unstructured.c:500
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)
#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 control_predecessors(x)
Definition: ri.h:943
#define statement_ordering(x)
Definition: ri.h:2454
#define unstructured_exit(x)
Definition: ri.h:3006
void print_text(FILE *fd, text t)
Definition: print.c:195

References ADD_SENTENCE_TO_TEXT, blocks, CAR, CHAIN_SWORD, CONTROL, CONTROL_MAP, control_predecessors, control_statement, control_successors, debug(), decorate_trail(), dump_control_to_label_name(), dump_trail(), fprintf(), gen_free_list(), gen_length(), gen_nreverse(), get_bool_property(), get_comment_sentinel(), hash_pointer, hash_table_free(), hash_table_make(), ifdebug, is_sentence_unformatted, make_sentence(), make_text(), make_unformatted(), MAPL, MERGE_TEXTS, module, NIL, num, ORDERING_NUMBER, ORDERING_STATEMENT, output_a_graph_view_of_the_unstructured(), print_text(), statement_identification(), statement_ordering, strdup(), text_statement(), text_trail(), unstructured_control, unstructured_exit, and unstructured_to_trail().

Referenced by text_instruction().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ unstructured_to_trail()

list unstructured_to_trail ( unstructured  u)

The exit node must be first (i.e. last) to reach the continuation of the unstructured, or never reached (e.g. because the program loops forever or stops in the unstructured).

Definition at line 240 of file unstructured.c.

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 }
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

References build_trail(), CAR, CONS, CONTROL, control_in_trail_p(), gen_remove(), NIL, unstructured_control, and unstructured_exit.

Referenced by c_unstructured(), ensure_comment_consistency(), last_statement(), new_points_to_unstructured(), and text_unstructured().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: