PIPS
look_for_nested_loops.c
Go to the documentation of this file.
1 /*
2 
3  $Id: look_for_nested_loops.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 /* Package generation (for the hyperplane transformation?)
28  */
29 
30 #include <stdio.h>
31 
32 #include "linear.h"
33 
34 #include "genC.h"
35 #include "ri.h"
36 #include "effects.h"
37 #include "misc.h"
38 #include "ri-util.h"
39 #include "effects-util.h"
40 #include "text.h"
41 #include "text-util.h"
42 #include "constants.h"
43 
44 #include "boolean.h"
45 #include "vecteur.h"
46 #include "contrainte.h"
47 #include "sc.h"
48 
49 #include "conversion.h"
50 
51 
52 /* void look_for_nested_loop_statements(statement s)
53  * search the nested loops in the statement s
54  *
55  */
57  statement (*loop_transformation)(list, bool (*)(statement)),
58  bool (*loop_predicate)(statement))
59 {
60  instruction i;
61  cons *b, *b1;
62  statement ss, new_s = statement_undefined;
63  loop l;
64  cons *list_loop_statement;
65  test tt;
66  statement true_s, false_s;
67 
68  i = statement_instruction(s);
69  switch (instruction_tag(i)) {
71  new_s = s;
72  l = instruction_loop(i);
73 
74  if ((*loop_predicate)(s)) {
75  list_loop_statement = CONS (STATEMENT,s,NIL);
76 
77  /* ifdebug(9) { */
78  /* pips_debug(9, "Before transformation:\n"); */
79  /* debug_on("ZERO_DEBUG_LEVEL"); */
80  /* print_statement(s); */
81  /* debug_off(); */
82  /* } */
83 
84  new_s = look_for_inner_loops(l,
85  list_loop_statement,
86  loop_transformation,
87  loop_predicate);
88 
89  ifdebug(9) {
90  pips_debug(9, "After transformation:\n");
91  pips_assert("look_for_nested_loop_statement", statement_consistent_p(new_s));
92  /* debug_on("ZERO_DEBUG_LEVEL"); */
93  /* print_statement(new_s); */
94  /* debug_off(); */
95  }
96  if (new_s != statement_undefined) {
97  i = statement_instruction(s);
98  instruction_loop(i) =
100  }
101  else look_for_nested_loop_statements(loop_body(l),loop_transformation,
102  loop_predicate);
103  break;
104 
106 
107  b = instruction_block(i);
108  if(ENDP(b)) break;
109  ss = STATEMENT(CAR(b));
110  /* SG: added to cope with empty statements */
111  while(empty_statement_or_continue_p(ss) && !ENDP(CDR(b))) {
112  POP(b);
113  ss=STATEMENT(CAR(b));
114  }
115  look_for_nested_loop_statements(ss, loop_transformation, loop_predicate);
116  for(b1 = CDR(b); !ENDP(b1); b1 = CDR(b1)) {
117  ss = STATEMENT(CAR(b1));
118  look_for_nested_loop_statements(ss, loop_transformation, loop_predicate);
119  }
120  break;
121 
122  case is_instruction_call:
123  break;
124 
125  case is_instruction_test:
126 
127  tt = instruction_test(i);
128  true_s = test_true(tt);
129  false_s= test_false(tt);
130  look_for_nested_loop_statements(true_s, loop_transformation, loop_predicate);
131  look_for_nested_loop_statements(false_s, loop_transformation, loop_predicate);
132  break;
133 
135 
137  statement body = whileloop_body(wl);
138 
139  look_for_nested_loop_statements(body, loop_transformation, loop_predicate);
140  break;
141  }
142 
143  case is_instruction_forloop: {
144 
146  statement body = forloop_body(fl);
147 
148  look_for_nested_loop_statements(body, loop_transformation, loop_predicate);
149  break;
150  }
151 
154  loop_transformation,
155  loop_predicate);
156  break;
157 
158  case is_instruction_goto:
159  pips_internal_error("unexpected goto in code");
160  default:
161  pips_internal_error("unexpected tag %d",instruction_tag(i));
162  }
163 }
164 
165 /* FI: I do not understand how debug levels are managed... They should be factored out. */
167  list sl,
168  statement (*loop_transformation)(list, bool (*)(statement)),
169  bool (*loop_predicate)(statement))
170 
171 {
172  statement lb = loop_body(l);
174  statement ss;
176  unstructured unst;
177  loop li;
178  cons *b, *b1;
179  test tt;
180  statement true_s, false_s;
181 
182  /* check that i is a block */
183  switch (instruction_tag(i)) {
184 
185  case is_instruction_loop:
186 
187  li = instruction_loop(i);
188  sl = CONS(STATEMENT,lb,sl);
189  new_s = look_for_inner_loops(li,sl,loop_transformation, loop_predicate);
190  break;
191 
193 retry:
194  b = instruction_block(i);
195  ss = STATEMENT(CAR(b));
196  /* SG: added to cope with empty statements */
197  while(empty_statement_or_continue_p(ss) && !ENDP(CDR(b))) {
198  POP(b);
199  ss=STATEMENT(CAR(b));
200  }
201  i = statement_instruction(ss);
202  if (instruction_block_p(i))
203  goto retry;
204  if (instruction_loop_p(i)){
205  /* i is an inner loop, append it to the list of loops */
206  li = instruction_loop(i);
207  sl = CONS(STATEMENT,ss,sl);
208  new_s = look_for_inner_loops(li, sl, loop_transformation, loop_predicate);
209  }
210  else {
211  /*there are no more nested loops */
212 
213  look_for_nested_loop_statements(ss,loop_transformation, loop_predicate);
214  debug_on("ZERO_DEBUG_LEVEL");
215  new_s = (*loop_transformation)(sl,loop_predicate);
216  debug_off();
217  }
218 
219  for( b1=CDR(b); !ENDP(b1); b1 = CDR(b1) ) {
220  ss = STATEMENT(CAR(b1));
221  look_for_nested_loop_statements(ss,loop_transformation, loop_predicate);
222  }
223  break;
224 
225 
226  ␌
227  case is_instruction_test:
228 
229  tt = instruction_test(i);
230  true_s = test_true(tt);
231  false_s= test_false(tt);
232  look_for_nested_loop_statements(true_s,loop_transformation, loop_predicate);
233  look_for_nested_loop_statements(false_s,loop_transformation, loop_predicate);
234  debug_on("ZERO_DEBUG_LEVEL");
235  new_s = (*loop_transformation)(sl,loop_predicate);
236  debug_off();
237  break;
238 
241 
242  look_for_nested_loop_statements(body, loop_transformation, loop_predicate);
243  new_s = (*loop_transformation)(sl,loop_predicate);
244  break;
245  }
246 
247  case is_instruction_forloop: {
249 
250  look_for_nested_loop_statements(body, loop_transformation, loop_predicate);
251  new_s = (*loop_transformation)(sl,loop_predicate);
252  break;
253  }
254  case is_instruction_goto:
255 
256  pips_internal_error("unexpected goto");
257 
258  case is_instruction_call:
259  debug_on("ZERO_DEBUG_LEVEL");
260  new_s = (*loop_transformation)(sl,loop_predicate);
261  debug_off();
262 
263  break;
264 
266 
267  /* FI: I do not understand this piece of code. I expect a
268  look_for_nested_loop_statements(). */
269  unst =instruction_unstructured(i);
271  i = statement_instruction(ss);
272  if (instruction_loop_p(i)) {
273  li = instruction_loop(i);
274  sl = CONS(STATEMENT,ss,sl);
275  new_s = look_for_inner_loops(li,sl,loop_transformation, loop_predicate);
276  }
277  else {
278  debug_on("ZERO_DEBUG_LEVEL");
279  new_s = (*loop_transformation)(sl,loop_predicate);
280  debug_off();
281  break;
282  }
283  break;
284 
285  default:
286  pips_internal_error("unexpected tag %d",instruction_tag(i));
287  }
288 
289  return new_s;
290 }
291 
292 ␌
293 
294 /*void look_for_nested_loops_unstructured(unstructured u)
295  * search the nested loops contained in the
296  * unstructured u
297  */
299  statement (*loop_transformation) (list, bool (*)(statement)),
300  bool (*loop_predicate)(statement))
301 {
302  cons *blocs = NIL;
304 
305  debug_on("GENERATION_DEBUG_LEVEL");
306  CONTROL_MAP(c, {
307  statement st = control_statement(c) ;
308  (void) look_for_nested_loop_statements(st,loop_transformation, loop_predicate);
309  }, ct, blocs) ;
310  gen_free_list(blocs);
311  debug_off();
312 }
bool statement_consistent_p(statement p)
Definition: ri.c:2195
#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
#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
#define CONS(_t_, _i_, _l_)
List element cell constructor (insert an element at the beginning of a list)
Definition: newgen_list.h:150
#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
bool empty_statement_or_continue_p(statement)
Return true if the statement is an empty instruction block or a continue or a recursive combination o...
Definition: statement.c:474
statement look_for_inner_loops(loop l, list sl, statement(*loop_transformation)(list, bool(*)(statement)), bool(*loop_predicate)(statement))
FI: I do not understand how debug levels are managed...
void look_for_nested_loop_statements(statement s, statement(*loop_transformation)(list, bool(*)(statement)), bool(*loop_predicate)(statement))
Package generation (for the hyperplane transformation?)
void look_for_nested_loops_unstructured(unstructured u, statement(*loop_transformation)(list, bool(*)(statement)), bool(*loop_predicate)(statement))
oid look_for_nested_loops_unstructured(unstructured u) search the nested loops contained in the unstr...
#define debug_on(env)
Definition: misc-local.h:157
#define pips_debug
these macros use the GNU extensions that allow variadic macros, including with an empty list.
Definition: misc-local.h:145
#define pips_assert(what, predicate)
common macros, two flavors depending on NDEBUG
Definition: misc-local.h:172
#define pips_internal_error
Definition: misc-local.h:149
#define debug_off()
Definition: misc-local.h:160
#define instruction_block_p(i)
#define unstructured_control
After the modification in Newgen: unstructured = entry:control x exit:control we have create a macro ...
#define is_instruction_block
soft block->sequence transition
#define instruction_block(i)
#define loop_body(x)
Definition: ri.h:1644
#define instruction_loop_p(x)
Definition: ri.h:1518
#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_test
Definition: ri.h:1470
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_forloop
Definition: ri.h:1477
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define test_true(x)
Definition: ri.h:2835
#define instruction_forloop(x)
Definition: ri.h:1538
#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 control_statement(x)
Definition: ri.h:941
#define instruction_test(x)
Definition: ri.h:1517
#define forloop_body(x)
Definition: ri.h:1372
#define instruction_unstructured(x)
Definition: ri.h:1532
#define statement_undefined
Definition: ri.h:2419
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
Value b1
booleen indiquant quel membre est en cours d'analyse
Definition: sc_gram.c:105
#define ifdebug(n)
Definition: sg.c:47
The structure used to build lists in NewGen.
Definition: newgen_list.h:41