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

Go to the source code of this file.

Macros

#define reached_p(s)   (bound_reached_p(s))
 A mapping to store if a given statement is reachable from the control flow point of view: More...
 
#define continued_p(s)   (load_continued(s))
 
#define check_recursion(s)
 

Functions

static bool propagate (statement s)
 returns whether propagation is continued after s. More...
 
static bool control_propagate (control c)
 
void init_reachable (statement start)
 Compute reachable infomation from the. More...
 
bool statement_reachable_p (statement s)
 Test if the given statement is reachable from some statements given at init_reachable(start) More...
 
bool statement_continued_p (statement s)
 Test if the execution goes on after the given statement. More...
 
void close_reachable (void)
 Remove reachability information about previously checked statements. More...
 

Macro Definition Documentation

◆ check_recursion

#define check_recursion (   s)
Value:
do { \
if (reached_p(s)) { \
if (bound_continued_p(s)) { \
pips_debug(5, "Statement %p already seen, thus stop recursion.\n", s); \
return continued_p(s); /**already computed */ \
} \
else { \
pips_debug(5, "Statement %p marked as reached but the execution does not continue on afterwards.\n\tSo return FALSE.\n", s); \
return false; /**avoids an infinite recursion... */ \
} \
} \
else { \
pips_debug(5, "New statement %p marked as reached.\n", s); \
store_reached(s, true); \
} \
} while (false) /**Pattern to be able to use this macro like an instruction. */
#define continued_p(s)
Definition: unreachable.c:51
#define reached_p(s)
A mapping to store if a given statement is reachable from the control flow point of view:
Definition: unreachable.c:50

Definition at line 55 of file unreachable.c.

◆ continued_p

#define continued_p (   s)    (load_continued(s))

Definition at line 51 of file unreachable.c.

◆ reached_p

#define reached_p (   s)    (bound_reached_p(s))

A mapping to store if a given statement is reachable from the control flow point of view:

Definition at line 50 of file unreachable.c.

Function Documentation

◆ close_reachable()

void close_reachable ( void  )

Remove reachability information about previously checked statements.

Definition at line 252 of file unreachable.c.

253 {
254  close_reached();
255  close_continued();
256 }

Referenced by module_name_to_preconditions(), and module_name_to_total_preconditions().

+ Here is the caller graph for this function:

◆ control_propagate()

static bool control_propagate ( control  c)
static

If we already have dealt with the current control node, stop the recursion:

already computed

Investigate about the continuation status of the statement:

Investigate the control successors only if the current one continues afterwards

It seems like a fallacy here. It is not semantically different if we have a cycle with more than 1 goto... It does not work for irreductible graphs either but it is detected anyway now in proagate(). RK

1 GO TO 1

Definition at line 74 of file unreachable.c.

75 {
76  list lc = control_successors(c);
77  int len = gen_length(lc);
79  pips_assert("max 2 successors", len<=2);
80  pips_debug(1, "Entering control_propagate for control %p\n", c);
81 
82  /* If we already have dealt with the current control node, stop the
83  recursion: */
84  if (reached_p(s) && bound_continued_p(s)) {
85  /* already computed */
86  pips_debug(5, "Statement %p already seen, thus stop recursion.\n", s);
87  return continued_p(s);
88  } \
89  /* Investigate about the continuation status of the statement: */
90  bool continued = propagate(s);
91 
92  if (continued) {
93  /* Investigate the control successors only if the current one
94  continues afterwards */
95  if (len==2) {
96  bool ctrue, cfalse;
97  ctrue = control_propagate(CONTROL(CAR(lc)));
98  cfalse = control_propagate(CONTROL(CAR(CDR(lc))));
99  // Continue after the test only if at leat one branch goes on:
100  continued = ctrue || cfalse;
101  }
102  else if (len==1) {
103  control cn = CONTROL(CAR(lc));
104  if (cn!=c) continued = control_propagate(cn);
105  /* It seems like a fallacy here. It is not semantically different if
106  we have a cycle with more than 1 goto... It does not work for
107  irreductible graphs either but it is detected anyway now in
108  proagate(). RK */
109  else continued = false; /* 1 GO TO 1 */
110  }
111  }
112  pips_debug(1, "Ending control_propagate for control %p and statement %p returning continued %d\n",
113  c, s, continued);
114  // store_continued(control_statement(c), continued);
115  return continued;
116 }
size_t gen_length(const list l)
Definition: list.c:150
#define CAR(pcons)
Get the value of the first element of a list.
Definition: newgen_list.h:92
#define CDR(pcons)
Get the list less its first element.
Definition: newgen_list.h:111
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define CONTROL(x)
CONTROL.
Definition: ri.h:910
#define control_successors(x)
Definition: ri.h:945
#define control_statement(x)
Definition: ri.h:941
The structure used to build lists in NewGen.
Definition: newgen_list.h:41
static bool propagate(statement)
returns whether propagation is continued after s.
Definition: unreachable.c:124
static bool control_propagate(control c)
Definition: unreachable.c:74

References CAR, CDR, continued_p, CONTROL, control_statement, control_successors, gen_length(), pips_assert, pips_debug, propagate(), and reached_p.

Referenced by propagate().

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

◆ init_reachable()

void init_reachable ( statement  start)

Compute reachable infomation from the.

unreachable.c

Parameters
startstatement.
Parameters
starttart

Definition at line 223 of file unreachable.c.

223  {
224  debug_on("REACHABLE_DEBUG_LEVEL");
225  init_reached();
226  init_continued();
227  propagate(start);
228  debug_off();
229 }
static char start[1024]
The name of the variable from which to start counting domain numbers.
Definition: genLisp.c:55
#define debug_on(env)
Definition: misc-local.h:157
#define debug_off()
Definition: misc-local.h:160

References debug_off, debug_on, propagate(), and start.

Referenced by module_name_to_preconditions(), and module_name_to_total_preconditions().

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

◆ propagate()

static bool propagate ( statement  s)
static

returns whether propagation is continued after s.

(that is no STOP or infinite loop encountered ??? ). It is a MAY information. If there is no propagation, it is a MUST information.

ifdebug(5) {

pips_debug(1, "Dealing with statement %p\n", s);

print_statement(s);

}

Undecidable implies "propagate" by default

Undecidable implies "propagate" by default

If the unstructured is seen as going on, test if the exit node as been marked as reachable

Since the exit node is not reached, that means that there is an infinite loop is the unstructured, so globally it is not continued:

FI: not satisfying; interprocedural control effects required here

FI: interprocedural exit possible:-(

FI: undone by the controlizer?

Definition at line 124 of file unreachable.c.

124  {
125  bool continued = true;
126  instruction i;
127 
128  pips_assert("defined statement", !statement_undefined_p(s));
129  /* ifdebug(5) { */
130  /* pips_debug(1, "Dealing with statement %p\n", s); */
131  /* print_statement(s); */
132  /* } */
133 
134  check_recursion(s);
135 
136  i = statement_instruction(s);
137  switch (instruction_tag(i))
138  {
140  {
142  while (l && (continued=propagate(STATEMENT(CAR(l)))))
143  POP(l);
144  break;
145  }
146  case is_instruction_loop:
147  {
149  break;
150  }
152  {
153  /* Undecidable implies "propagate" by default */
155  break;
156  }
158  {
159  /* Undecidable implies "propagate" by default */
161  break;
162  }
163  case is_instruction_test:
164  {
165  test t = instruction_test(i);
166  bool ctrue, cfalse;
167  ctrue = propagate(test_true(t));
168  cfalse = propagate(test_false(t));
169  continued = ctrue || cfalse;
170  break;
171  }
173  {
176  // Investigate inside the unstructured control graph:
177  continued = control_propagate(c);
178  if (continued) {
179  /* If the unstructured is seen as going on, test if the exit node
180  as been marked as reachable */
182  if (!reached_p(exit))
183  /* Since the exit node is not reached, that means that there is
184  an infinite loop is the unstructured, so globally it is not
185  continued: */
186  continued = false;
187  }
188  break;
189  }
190  case is_instruction_call:
191  {
192  /* FI: not satisfying; interprocedural control effects required here */
195  break;
196  }
198  {
199  continued = true; /* FI: interprocedural exit possible:-( */
200  break;
201  }
203  {
204  pips_internal_error("Not implemented yet"); /* FI: undone by the controlizer? */
205  break;
206  }
207  case is_instruction_goto:
208  pips_internal_error("GOTO should have been eliminated by the controlizer");
209  break;
210  default:
211  pips_internal_error("unexpected instruction tag");
212  }
213 
214  pips_debug(1, "Continued for statement %p = %d\n", s, continued);
215  store_continued(s, continued);
216  return continued;
217 }
#define POP(l)
Modify a list pointer to point on the next element of the list.
Definition: newgen_list.h:59
#define pips_internal_error
Definition: misc-local.h:149
#define exit(code)
Definition: misc-local.h:54
int f(int off1, int off2, int n, float r[n], float a[n], float b[n])
Definition: offsets.c:15
#define ENTITY_STOP_P(e)
#define ENTITY_EXIT_SYSTEM_P(e)
#define unstructured_control
After the modification in Newgen: unstructured = entry:control x exit:control we have create a macro ...
#define ENTITY_ABORT_SYSTEM_P(e)
#define loop_body(x)
Definition: ri.h:1644
#define call_function(x)
Definition: ri.h:709
#define instruction_loop(x)
Definition: ri.h:1520
#define test_false(x)
Definition: ri.h:2837
@ 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_multitest
Definition: ri.h:1476
@ 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 test_true(x)
Definition: ri.h:2835
#define sequence_statements(x)
Definition: ri.h:2360
#define instruction_sequence(x)
Definition: ri.h:1514
#define instruction_forloop(x)
Definition: ri.h:1538
#define unstructured_exit(x)
Definition: ri.h:3006
#define instruction_whileloop(x)
Definition: ri.h:1523
#define whileloop_body(x)
Definition: ri.h:3162
#define statement_instruction(x)
Definition: ri.h:2458
#define instruction_call(x)
Definition: ri.h:1529
#define instruction_test(x)
Definition: ri.h:1517
#define statement_undefined_p(x)
Definition: ri.h:2420
#define forloop_body(x)
Definition: ri.h:1372
#define instruction_unstructured(x)
Definition: ri.h:1532
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
#define check_recursion(s)
Definition: unreachable.c:55

References call_function, CAR, check_recursion, control_propagate(), control_statement, ENTITY_ABORT_SYSTEM_P, ENTITY_EXIT_SYSTEM_P, ENTITY_STOP_P, exit, f(), forloop_body, instruction_call, instruction_forloop, instruction_loop, instruction_sequence, instruction_tag, instruction_test, instruction_unstructured, instruction_whileloop, is_instruction_call, is_instruction_expression, is_instruction_forloop, is_instruction_goto, is_instruction_loop, is_instruction_multitest, is_instruction_sequence, is_instruction_test, is_instruction_unstructured, is_instruction_whileloop, loop_body, pips_assert, pips_debug, pips_internal_error, POP, reached_p, sequence_statements, STATEMENT, statement_instruction, statement_undefined_p, test_false, test_true, unstructured_control, unstructured_exit, and whileloop_body.

Referenced by control_propagate(), and init_reachable().

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

◆ statement_continued_p()

bool statement_continued_p ( statement  s)

Test if the execution goes on after the given statement.

For example it is false after a "return" in C

Definition at line 242 of file unreachable.c.

243 {
244  if (bound_continued_p(s))
245  return continued_p(s);
246  else
247  return false;
248 }

References continued_p.

◆ statement_reachable_p()

bool statement_reachable_p ( statement  s)

Test if the given statement is reachable from some statements given at init_reachable(start)

Definition at line 234 of file unreachable.c.

235 {
236  return reached_p(s);
237 }

References reached_p.

Referenced by statement_to_postcondition(), and statement_to_total_precondition().

+ Here is the caller graph for this function: