PIPS
reorder.c
Go to the documentation of this file.
1 /*
2 
3  $Id: reorder.c 23172 2016-08-30 08:18:16Z 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 #include <stdio.h>
28 #include <strings.h>
29 
30 #include "linear.h"
31 
32 #include "genC.h"
33 #include "ri.h"
34 
35 #include "misc.h"
36 #include "ri-util.h"
37 
38 /** @file reorder.c
39 
40  @brief These functions compute the statement_ordering of their arguments.
41 
42  To ease referencing statements, statements are numbered with an
43  ordering that is made of 2 parts, an unstructured order that is the
44  occurence order of unstructured control node in a depth first visit of
45  the RI, and a local order that corresponds to appearance order in a
46  depth first visit of the statements inside a control node. This last
47  number in reset to one when encountering a control node.
48 */
49 
50 /* The current unstructured number, that is the number of control node
51  encountered during depth first visiting */
52 static int u_number;
53 
54 
55 /* Reset the unstructured number for a new module reordering. */
57  u_number = 0;
58 }
59 
60 
61 /* Compute the next unstructured order */
63  return u_number;
64 }
65 
66 
67 /* Compute the next unstructured order */
69  return ++u_number;
70 }
71 
72 /* Compute the statement ordering of a statement and all its components
73 
74  This function should be rewritten with a gen_multi_recurse_context() on
75  statements and controls...
76 
77  @param st is the statement which we want to compute the ordering
78  @param un is the unstructured number before statement entry
79  @param st is the statement number before statement entry
80 
81  @return the statement number after the end of the given statement
82 */
83 static int statement_reorder(statement st, int un, int sn, bool *changed)
84 {
86  pips_assert("instruction is defined", !instruction_undefined_p(i));
87 
88  // temporary, just to avoid rebooting...
89  static int check_depth_hack = 0;
90  check_depth_hack++;
91  pips_assert("not too deep", check_depth_hack<10000);
92 
93  pips_debug(5, "entering for %"_intFMT" : (%d,%d)\n",
94  statement_number(st), un, sn);
95 
96  // update ordering if needed
97  int new_order = MAKE_ORDERING(un, sn);
98  if (new_order != statement_ordering(st))
99  {
100  statement_ordering(st) = new_order;
101  *changed = true;
102  }
103  sn += 1;
104 
105  switch (instruction_tag(i))
106  {
108  pips_debug(5, "sequence\n");
110  sn = statement_reorder(s, un, sn, changed);
111  break;
112  case is_instruction_test:
113  pips_debug(5, "test\n");
114  sn = statement_reorder(test_true(instruction_test(i)), un, sn, changed);
115  sn = statement_reorder(test_false(instruction_test(i)), un, sn, changed);
116  break;
117  case is_instruction_loop:
118  pips_debug(5, "loop\n");
119  sn = statement_reorder(loop_body(instruction_loop(i)), un, sn, changed);
120  break;
122  pips_debug(5, "whileloop\n");
124  un, sn, changed);
125  break;
127  pips_debug(5, "forloop\n");
129  un, sn, changed);
130  break;
131  case is_instruction_goto:
132  case is_instruction_call:
133  pips_debug(5, "goto or call\n");
134  // nothing to do, does not contain statements
135  break;
137  pips_debug(5, "expression\n");
138  break;
140  pips_debug(5, "unstructured\n");
142  break;
143  // missing: is_instruction_multitest
144  default:
145  pips_internal_error("Unknown tag %d", instruction_tag(i));
146  }
147  pips_debug(5, "exiting %d\n", sn);
148  check_depth_hack--;
149  return sn;
150 }
151 
152 
154  __attribute__((unused)) set visited_control) {
155 }
156 
157 /* Reorder an unstructured
158 
159  All the nodes of the unstructured are numbered, first the reachable one
160  and the the unreachable ones if any.
161 
162  @param u the unstructured to reorder.
163 
164  this function is used by control/old_controlizer.c
165 */
167 {
168  bool changed = false;
169  /* To store the visited nodes by CONTROL_MAP and avoid visiting twice a
170  control node: */
171  list blocs = NIL;
172  /* To avoid renaming twice a control node statement, keep track of the
173  visited statements: */
174  // set visited_control =
175 
176  pips_debug(2, "entering\n");
177 
178  /* First iterate on the reachable control nodes from the entry node of
179  the unstructured and then from the exit node: */
180  UNSTRUCTURED_CONTROL_MAP(c, u, blocs, {
182  /* Since we enter a control node, increase the unstructured
183  order: */
184  int un = get_next_unstructured_number();
185 
186  pips_debug(3, "will reorder %ld %d\n", statement_number(st), un);
187  /* ifdebug(3) */
188  /* print_statement(st); */
189 
190  /* Since we enter a control node, number the statements inside this
191  control node with a statement number starting from 1: */
192  statement_reorder(st, un, 1, &changed);
193  });
194 
195  /* Free the list build up during the visit: */
196  gen_free_list(blocs);
197 
198  debug(3, "unstructured_reorder", "exiting\n");
199 
200  return changed;
201 }
202 
203 
204 /* Reorder a module
205 
206  This recompute the ordering of a module, that is the ordering number of
207  all the statements in the module..
208 
209  @param body is the top-level statement of the module to reorder
210 */
212 {
213  /* If a module_body_reorder() is required, ordering_to_statement must be
214  recomputed if any. So use module_reorder() instead of the low-level
215  module_body_reorder(): */
216  pips_assert("ordering to statement is not initialized",
218 
219  debug_on("CONTROL_DEBUG_LEVEL");
220 
222 
223  /* Reorder the module statements by beginning with unstructured number
224  and statement number at 1 */
225  bool changed = false;
226  statement_reorder(body, get_unstructured_number(), 1, &changed);
227 
228  debug_off();
229 
230  return changed;
231 }
232 
233 
234 /* Reorder a module and recompute order to statement if any.
235 
236  This recompute the ordering of a module, that is the ordering number of
237  all the statements in the module..
238 
239  If there is also already a mapping from the ordering to the statements,
240  it is reset and recompute after reordering.
241 
242  @param body is the top-level statement of the module to reorder
243  */
245 {
246  bool ordering_mapping_used = ordering_to_statement_initialized_p();
247  if(ordering_mapping_used)
248  /* There was a mapping to associate a statement to a given ordering,
249  so clean it: */
251 
252  bool changed = module_body_reorder(body);
253 
254  if (ordering_mapping_used) {
255  /* There was a mapping to associate a statement to a given ordering,
256  so we recompute it: */
258  /* FI: I'd rather use set_ordering_to_statement() so that reset are
259  properly called and no outdated ots hash table remains for ever in
260  the background, but I do not want to break PIPS right now.
261 
262  How do you know ordering to statement to be useful in the future?
263 
264  May be, we are going to work on a different module very soon..
265  */
266  }
267 
268  return changed;
269 }
float a2sf[2] __attribute__((aligned(16)))
USER generates a user error (i.e., non fatal) by printing the given MSG according to the FMT.
Definition: 3dnow.h:3
#define UNSTRUCTURED_CONTROL_MAP(c, u, l, code)
Walk through all the controls of un unstructured.
#define NIL
The empty list (nil in Lisp)
Definition: newgen_list.h:47
void gen_free_list(list l)
free the spine of the list
Definition: list.c:327
#define FOREACH(_fe_CASTER, _fe_item, _fe_list)
Apply/map an instruction block on all the elements of a list.
Definition: newgen_list.h:179
#define 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
void debug(const int the_expected_debug_level, const char *calling_function_name, const char *a_message_format,...)
ARARGS0.
Definition: debug.c:189
#define _intFMT
Definition: newgen_types.h:57
hash_table set_ordering_to_statement(statement s)
To be used instead of initialize_ordering_to_statement() to make sure that the hash table ots is in s...
Definition: ordering.c:172
void reset_ordering_to_statement(void)
Reset the mapping from ordering to statement.
Definition: ordering.c:185
bool ordering_to_statement_initialized_p()
Test if the ordering to statement is initialized.
Definition: ordering.c:63
static int statement_reorder(statement st, int un, int sn, bool *changed)
Compute the statement ordering of a statement and all its components.
Definition: reorder.c:83
void control_node_reorder(__attribute__((unused)) control c, __attribute__((unused)) set visited_control)
Definition: reorder.c:153
static int get_next_unstructured_number()
Compute the next unstructured order.
Definition: reorder.c:68
bool module_reorder(statement body)
Reorder a module and recompute order to statement if any.
Definition: reorder.c:244
void reset_unstructured_number()
Reset the unstructured number for a new module reordering.
Definition: reorder.c:56
bool module_body_reorder(statement body)
Reorder a module.
Definition: reorder.c:211
static int u_number
The current unstructured number, that is the number of control node encountered during depth first vi...
Definition: reorder.c:52
static int get_unstructured_number()
Compute the next unstructured order.
Definition: reorder.c:62
bool unstructured_reorder(unstructured u)
Reorder an unstructured.
Definition: reorder.c:166
#define MAKE_ORDERING(u, s)
On devrait utiliser Newgen pour cela, mais comme on ne doit pas les utiliser directement (mais via st...
#define loop_body(x)
Definition: ri.h:1644
#define instruction_loop(x)
Definition: ri.h:1520
#define statement_ordering(x)
Definition: ri.h:2454
#define test_false(x)
Definition: ri.h:2837
#define instruction_undefined_p(x)
Definition: ri.h:1455
@ is_instruction_goto
Definition: ri.h:1473
@ is_instruction_unstructured
Definition: ri.h:1475
@ is_instruction_whileloop
Definition: ri.h:1472
@ is_instruction_expression
Definition: ri.h:1478
@ is_instruction_test
Definition: ri.h:1470
@ is_instruction_call
Definition: ri.h:1474
@ is_instruction_sequence
Definition: ri.h:1469
@ is_instruction_forloop
Definition: ri.h:1477
@ is_instruction_loop
Definition: ri.h:1471
#define instruction_tag(x)
Definition: ri.h:1511
#define 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 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 statement_number(x)
Definition: ri.h:2452
#define forloop_body(x)
Definition: ri.h:1372
#define instruction_unstructured(x)
Definition: ri.h:1532
FI: I do not understand why the type is duplicated at the set level.
Definition: set.c:59
The structure used to build lists in NewGen.
Definition: newgen_list.h:41