PIPS
compiler-util.c
Go to the documentation of this file.
1 /*
2 
3  $Id: compiler-util.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 /* Compiler Utilities
28  *
29  * Fabien Coelho, May 1993
30  */
31 
32 #include "defines-local.h"
33 
34 /***************************************************************************/
35 
37 control c;
38 control_mapping map;
39 {
40  control cprime = (control) GET_CONTROL_MAPPING(map, c);
41 
42  pips_assert("empty lists for cprime",
43  control_predecessors(cprime)==NIL &&
44  control_successors(cprime)==NIL);
45 
46  control_predecessors(cprime) =
48  control_successors(cprime) =
50 }
51 
53 list lc;
54 control_mapping map;
55 {
56  list lc_result = NIL;
57  control new_c = control_undefined;
58 
60  {
61  new_c = (control) GET_CONTROL_MAPPING(map, current);
62 
63  pips_assert("defined",
65  !control_undefined_p(new_c));
66 
67  lc_result = CONS(CONTROL, new_c, lc_result);
68  },
69  lc);
70 
71  return(gen_nreverse(lc_result));
72 }
73 
74 /* FindRefToDistArrayInStatement
75  *
76  * everything may be quite false regarding to the real effects of
77  * the functions called, but it seems to me that the pips effect analysis
78  * doesn't match my needs... and I have not much time to think about that...
79  *
80  * ??? these stupid functions assume no indirections on distributed arrays
81  * ??? also that they are not written by a function other than assign
82  */
83 static list
86 
87 #define call_assign_p(c) \
88  (strcmp(entity_local_name(call_function(c)), ASSIGN_OPERATOR_NAME)==0)
89 
91 call c;
92 {
93  list l;
94  syntax s;
95 
96  if (!call_assign_p(c)) return(true);
97 
98  /* else ASSIGN case
99  */
100 
101  l = call_arguments(c);
103 
106 
107  found_read =
109  found_read);
110 
111  return(false);
112 }
113 
115 expression e;
116 {
118  return(false);
119 }
120 
121 void FindRefToDistArrayInStatement(obj, lwp, lrp)
122 statement obj;
123 list *lwp, *lrp;
124 {
125  list
126  saved_r = found_read,
127  saved_w = found_written;
128 
130 
131  gen_multi_recurse(obj,
132  call_domain,
134  gen_null,
137  gen_null,
138  NULL);
139 
140  *lwp = found_written, *lrp = found_read,
141  found_read = saved_r, found_written = saved_w;
142 }
143 
144 
145 /* computes the list of indices of the list of ref that are variables...
146  */
148 list lsyn;
149 {
150  return((ENDP(lsyn))?
151  (NULL):
153  lIndicesOfRef(CDR(lsyn)))));
154 }
155 
157 syntax syn;
158 {
159  list l = NIL;
160 
161  pips_assert("reference", syntax_reference_p(syn));
162 
163  MAP(EXPRESSION, e,
164  {
165  syntax s = expression_syntax(e);
166 
167  switch (syntax_tag(s))
168  {
169  case is_syntax_reference:
170  l = CONS(SYNTAX, s, l);
171  break;
172  case is_syntax_range:
173  pips_internal_error("don't konw what to do with a range");
174  break;
175  case is_syntax_call:
176  /* ??? could check that the given call is a constant.
177  */
178  break;
179  default:
180  pips_internal_error("unexpected syntax tag");
181  }
182  },
184 
185  return(l);
186 }
187 
189 list l, lsyn;
190 {
191  MAP(SYNTAX, s,
193  lsyn = CONS(SYNTAX, s, lsyn),
194  l);
195 
196  gen_free_list(l);
197  return(lsyn);
198 }
199 
201 entity e;
202 list l;
203 {
204  MAP(SYNTAX, s,
205  if (e==reference_variable(syntax_reference(s))) return(true),
206  l);
207 
208  return(false);
209 }
210 
211 /* ??? False!
212  * The definition looked for must be an assignment call...
213  */
214 static list
217 
219 statement s;
220 {
222 
223  /* ??? False! nothing is checked about the statement movement...
224  */
225  if (instruction_assign_p(i))
230  syntax_list))
231  {
236  }
237 }
238 
240 statement stat;
241 list lsyn;
242 {
243  list result = NIL;
244 
245  pips_assert("empty lists", ENDP(syntax_list) && ENDP(found_definitions));
246 
247  syntax_list = lsyn;
248 
249  gen_recurse(stat,
251  gen_true,
253 
254  result = found_definitions,
255  syntax_list = NIL,
257 
258  return(result);
259 }
260 
261 /* atomic_accesses_only_p
262  *
263  * checks that only atomic accesses to distributed variables are made
264  * inside a parallel loop nest, for every iterations.
265  *
266  * ??? partially implemented, and the conclusions may be false...
267  */
269 {
270  ifdebug(1)
271  hpfc_warning("not implemented, returning TRUE\n");
272  return true;
273 }
274 
275 /* indirections_inside_statement_p
276  *
277  * ??? this may be checked using the dependences graph, looking for
278  * edges linking two distributed variables inside the loop...
279  */
281 {
282  ifdebug(1)
283  hpfc_warning("not implemented yet, returning FALSE\n");
284  return false;
285 }
286 
287 /* ------------------------------------------------------------------
288  * statement parallel_loop_nest_to_body(loop_nest, pblocks, ploops)
289  * statement loop_nest;
290  * list *pblocks, *ploops;
291  *
292  * What I want is to extract the parallel loops from loop_nest,
293  * while keeping track of the structure if the loop nest is not
294  * perfectly nested. Only a very simple structure is recognized.
295  *
296  * it returns the inner statement of the loop nest,
297  * a list of pointers to the loops, and a list of pointers
298  * to the blocks containing these loops if any.
299  *
300  * we may discuss the implementation based on static global variables...
301  * but I cannot see how to do it otherwise with a gen_recurse.
302  */
303 
304 static list
305  loops, /* lisp of loops */
306  blocks;/* list of lists, may be NIL if none */
307 static int n_loops, n_levels;
309 
310 static bool loop_filter(loop l)
311 {
313 }
314 
316 {
317  if (n_loops==0 && n_levels==0) /* there was no doall inside */
318  return;
319 
320  if (n_loops-n_levels!=1)
321  pips_internal_error("block within a block encountered");
322 
324 }
325 
326 static void loop_rewrite(loop l)
327 {
328  if (n_loops!=n_levels) /* a loop was found directly as a body */
329  n_levels++, blocks = CONS(LIST, NIL, blocks);
330 
331  if (n_loops==0) inner_body=loop_body(l);
332  loops = CONS(LOOP, l, loops);
333  n_loops++;
334 }
335 
336 statement parallel_loop_nest_to_body(loop_nest, pblocks, ploops)
337 statement loop_nest;
338 list *pblocks, *ploops;
339 {
340  loops=NIL, n_loops=0;
341  blocks=NIL, n_levels=0;
343 
345 
346  gen_multi_recurse(loop_nest,
349  NULL);
350 
351  pips_assert("loops found", n_loops!=0 && (n_loops-n_levels==1));
352 
353  *pblocks = CONS(LIST, NIL, blocks); /* nothing was done for the first ! */
354  *ploops=loops;
355 
356  return(inner_body);
357 }
358 
359 /************************************************************ CURRENT LOOPS */
360 
361 /* management of a list of current loops. very burk ???
362  */
363 
365 
367 {
369 }
370 
372 {
373  pips_assert("no current loop", current_loop_list==NIL);
375 }
376 
378 {
381 }
382 
384 entity e;
385 {
386  MAP(LOOP, l, if (e == loop_index(l)) return true, current_loop_list);
387  return false;
388 }
389 
391 entity index;
392 {
393  MAP(LOOP, l, if (loop_index(l)==index) return(loop_range(l)),
395  return range_undefined;
396 }
397 
398 /* that is all
399  */
static bool FindRefToDistArrayInStatement_call_filter(call c)
Definition: compiler-util.c:90
static void set_current_loops_rewrite(loop l)
static int n_loops
list of lists, may be NIL if none
static bool loop_filter(loop l)
static list blocks
lisp of loops
static list syntax_list
??? False! The definition looked for must be an assignment call...
statement parallel_loop_nest_to_body(statement loop_nest, list *pblocks, list *ploops)
bool indirections_inside_statement_p(_UNUSED_ statement stat)
indirections_inside_statement_p
static list found_written
FindRefToDistArrayInStatement.
Definition: compiler-util.c:84
list lIndicesOfRef(list lsyn)
computes the list of indices of the list of ref that are variables...
static void loop_rewrite(loop l)
bool entity_loop_index_p(entity e)
static void sequence_rewrite(sequence s)
list updated_control_list(list lc, control_mapping map)
Definition: compiler-util.c:52
range loop_index_to_range(entity index)
static list current_loop_list
management of a list of current loops.
static bool FindRefToDistArrayInStatement_expression_filter(expression e)
static list found_definitions
bool is_in_syntax_list(entity e, list l)
void reset_current_loops()
static void FindDefinitionsOf_rewrite(statement s)
#define call_assign_p(c)
Definition: compiler-util.c:87
static int n_levels
void set_current_loops(statement obj)
void FindRefToDistArrayInStatement(statement obj, list *lwp, list *lrp)
list FindDefinitionsOf(statement stat, list lsyn)
bool atomic_accesses_only_p(_UNUSED_ statement stat)
atomic_accesses_only_p
static list loops
void update_control_lists(control c, control_mapping map)
Compiler Utilities.
Definition: compiler-util.c:36
list IndicesOfRef(syntax syn)
static statement inner_body
static list found_read
Definition: compiler-util.c:85
list AddOnceToIndicesList(list l, list lsyn)
#define LIST(x)
Definition: genC.h:93
#define gen_recurse(start, domain_number, flt, rwt)
Definition: genC.h:283
statement instruction_to_statement(instruction)
Build a statement from a give instruction.
Definition: statement.c:597
void gen_multi_recurse(void *o,...)
Multi recursion visitor function.
Definition: genClib.c:3428
void gen_null(__attribute__((unused)) void *unused)
Ignore the argument.
Definition: genClib.c:2752
bool gen_true(__attribute__((unused)) gen_chunk *unused)
Return true and ignore the argument.
Definition: genClib.c:2780
instruction make_continue_instruction()
Creates a CONTINUE instruction, that is the FORTRAN nop, the ";" in C or the "pass" in Python for exa...
Definition: instruction.c:79
bool instruction_assign_p(instruction i)
Test if an instruction is an assignment.
Definition: instruction.c:164
#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
#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
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
#define MAP(_map_CASTER, _map_item, _map_code, _map_list)
Apply/map an instruction block on all the elements of a list (old fashioned)
Definition: newgen_list.h:226
list FindRefToDistArray(void *obj)
Definition: hpfc-util.c:282
#define hpfc_warning
WARNING.
bool array_distributed_p(entity)
struct _newgen_struct_control_ * control
#define _UNUSED_
Definition: misc-local.h:232
#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 GET_CONTROL_MAPPING(map, cont)
Definition: newgen-local.h:88
reference expression_reference(expression e)
Short cut, meaningful only if expression_reference_p(e) holds.
Definition: expression.c:1832
#define loop_body(x)
Definition: ri.h:1644
#define syntax_reference_p(x)
Definition: ri.h:2728
#define expression_domain
newgen_execution_domain_defined
Definition: ri.h:154
#define LOOP(x)
LOOP.
Definition: ri.h:1606
#define control_undefined
Definition: ri.h:916
#define loop_execution(x)
Definition: ri.h:1648
#define syntax_reference(x)
Definition: ri.h:2730
#define syntax_tag(x)
Definition: ri.h:2727
#define instruction_loop_p(x)
Definition: ri.h:1518
#define reference_variable(x)
Definition: ri.h:2326
#define loop_domain
newgen_language_domain_defined
Definition: ri.h:218
#define control_predecessors(x)
Definition: ri.h:943
#define range_undefined
Definition: ri.h:2263
#define statement_domain
newgen_sizeofexpression_domain_defined
Definition: ri.h:362
#define CONTROL(x)
CONTROL.
Definition: ri.h:910
@ is_syntax_range
Definition: ri.h:2692
@ is_syntax_call
Definition: ri.h:2693
@ is_syntax_reference
Definition: ri.h:2691
#define call_domain
newgen_callees_domain_defined
Definition: ri.h:58
#define EXPRESSION(x)
EXPRESSION.
Definition: ri.h:1217
#define sequence_statements(x)
Definition: ri.h:2360
#define reference_indices(x)
Definition: ri.h:2328
#define control_successors(x)
Definition: ri.h:945
#define control_undefined_p(x)
Definition: ri.h:917
#define statement_instruction(x)
Definition: ri.h:2458
#define instruction_call(x)
Definition: ri.h:1529
#define loop_range(x)
Definition: ri.h:1642
#define call_arguments(x)
Definition: ri.h:711
#define expression_syntax(x)
Definition: ri.h:1247
#define sequence_domain
newgen_reference_domain_defined
Definition: ri.h:346
#define execution_parallel_p(x)
Definition: ri.h:1211
#define loop_index(x)
Definition: ri.h:1640
#define statement_undefined
Definition: ri.h:2419
#define STATEMENT(x)
STATEMENT.
Definition: ri.h:2413
#define SYNTAX(x)
SYNTAX.
Definition: ri.h:2670
#define ifdebug(n)
Definition: sg.c:47
static size_t current
Definition: string.c:115
The structure used to build lists in NewGen.
Definition: newgen_list.h:41