]> gcc.gnu.org Git - gcc.git/blame - gcc/c-iterate.c
(collect_iterators, case SAVE_EXPR): Simplify code added in previous
[gcc.git] / gcc / c-iterate.c
CommitLineData
41424fdd 1/* Build expressions with type checking for C compiler.
93e4100a 2 Copyright (C) 1987, 1988, 1989, 1992, 1993 Free Software Foundation, Inc.
41424fdd
RS
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21/* This file is part of the C front end.
22 It is responsible for implementing iterators,
23 both their declarations and the expansion of statements using them. */
24
25#include "config.h"
26#include <stdio.h>
27#include "tree.h"
28#include "c-tree.h"
29#include "flags.h"
e26d4611
RS
30#include "obstack.h"
31#include "rtl.h"
41424fdd
RS
32
33static void expand_stmt_with_iterators_1 ();
09aab2de 34static tree collect_iterators ();
41424fdd
RS
35static void iterator_loop_prologue ();
36static void iterator_loop_epilogue ();
37static void add_ixpansion ();
38static void delete_ixpansion();
39static int top_level_ixpansion_p ();
40static void istack_sublevel_to_current ();
e26d4611
RS
41
42/* A special obstack, and a pointer to the start of
43 all the data in it (so we can free everything easily). */
44static struct obstack ixp_obstack;
45static char *ixp_firstobj;
41424fdd 46\f
e26d4611
RS
47/*
48 KEEPING TRACK OF EXPANSIONS
49
50 In order to clean out expansions corresponding to statements inside
51 "{(...)}" constructs we have to keep track of all expansions. The
52 cleanup is needed when an automatic, or implicit, expansion on
53 iterator, say X, happens to a statement which contains a {(...)}
54 form with a statement already expanded on X. In this case we have
55 to go back and cleanup the inner expansion. This can be further
56 complicated by the fact that {(...)} can be nested.
57
58 To make this cleanup possible, we keep lists of all expansions, and
59 to make it work for nested constructs, we keep a stack. The list at
60 the top of the stack (ITER_STACK.CURRENT_LEVEL) corresponds to the
61 currently parsed level. All expansions of the levels below the
62 current one are kept in one list whose head is pointed to by
63 ITER_STACK.SUBLEVEL_FIRST (SUBLEVEL_LAST is there for making merges
64 easy). The process works as follows:
65
66 -- On "({" a new node is added to the stack by PUSH_ITERATOR_STACK.
67 The sublevel list is not changed at this point.
68
69 -- On "})" the list for the current level is appended to the sublevel
70 list.
71
72 -- On ";" sublevel lists are appended to the current level lists.
73 The reason is this: if they have not been superseded by the
74 expansion at the current level, they still might be
75 superseded later by the expansion on the higher level.
76 The levels do not have to distinguish levels below, so we
77 can merge the lists together. */
78
79struct ixpansion
41424fdd 80{
e26d4611
RS
81 tree ixdecl; /* Iterator decl */
82 rtx ixprologue_start; /* First insn of epilogue. NULL means */
83 /* explicit (FOR) expansion*/
84 rtx ixprologue_end;
85 rtx ixepilogue_start;
86 rtx ixepilogue_end;
87 struct ixpansion *next; /* Next in the list */
88};
89
90struct iter_stack_node
91{
92 struct ixpansion *first; /* Head of list of ixpansions */
93 struct ixpansion *last; /* Last node in list of ixpansions */
94 struct iter_stack_node *next; /* Next level iterator stack node */
95};
96
97struct iter_stack_node *iter_stack;
98
99struct iter_stack_node sublevel_ixpansions;
09aab2de
RS
100
101/* During collect_iterators, a list of SAVE_EXPRs already scanned. */
102static tree save_exprs;
e26d4611
RS
103\f
104/* Initialize our obstack once per compilation. */
41424fdd
RS
105
106void
e26d4611 107init_iterators ()
41424fdd 108{
e26d4611
RS
109 gcc_obstack_init (&ixp_obstack);
110 ixp_firstobj = (char *) obstack_alloc (&ixp_obstack, 0);
41424fdd
RS
111}
112
e26d4611
RS
113/* Handle the start of an explicit `for' loop for iterator IDECL. */
114
41424fdd 115void
e26d4611 116iterator_for_loop_start (idecl)
41424fdd
RS
117 tree idecl;
118{
e26d4611 119 ITERATOR_BOUND_P (idecl) = 1;
41424fdd 120 add_ixpansion (idecl, 0, 0, 0, 0);
e26d4611 121 iterator_loop_prologue (idecl, 0, 0);
41424fdd
RS
122}
123
e26d4611 124/* Handle the end of an explicit `for' loop for iterator IDECL. */
41424fdd 125
e26d4611
RS
126void
127iterator_for_loop_end (idecl)
128 tree idecl;
129{
130 iterator_loop_epilogue (idecl, 0, 0);
131 ITERATOR_BOUND_P (idecl) = 0;
132}
133\f
41424fdd
RS
134/*
135 ITERATOR RTL EXPANSIONS
136
e26d4611
RS
137 Expanding simple statements with iterators is straightforward:
138 collect the list of all free iterators in the statement, and
139 generate a loop for each of them.
140
141 An iterator is "free" if it has not been "bound" by a FOR
142 operator. The DECL_RTL of the iterator is the loop counter. */
143
144/* Expand a statement STMT, possibly containing iterator usage, into RTL. */
41424fdd
RS
145
146void
147iterator_expand (stmt)
148 tree stmt;
149{
09aab2de
RS
150 tree iter_list;
151 save_exprs = NULL_TREE;
152 iter_list = collect_iterators (stmt, NULL_TREE);
41424fdd
RS
153 expand_stmt_with_iterators_1 (stmt, iter_list);
154 istack_sublevel_to_current ();
155}
156
157
158static void
159expand_stmt_with_iterators_1 (stmt, iter_list)
160 tree stmt, iter_list;
161{
162 if (iter_list == 0)
163 expand_expr_stmt (stmt);
164 else
165 {
166 tree current_iterator = TREE_VALUE (iter_list);
167 tree iter_list_tail = TREE_CHAIN (iter_list);
168 rtx p_start, p_end, e_start, e_end;
169
170 iterator_loop_prologue (current_iterator, &p_start, &p_end);
171 expand_stmt_with_iterators_1 (stmt, iter_list_tail);
172 iterator_loop_epilogue (current_iterator, &e_start, &e_end);
173
174 /** Delete all inner expansions based on current_iterator **/
175 /** before adding the outer one. **/
176
177 delete_ixpansion (current_iterator);
178 add_ixpansion (current_iterator, p_start, p_end, e_start, e_end);
179 }
180}
181
182
e26d4611
RS
183/* Return a list containing all the free (i.e. not bound by a
184 containing `for' statement) iterators mentioned in EXP, plus those
185 in LIST. Do not add duplicate entries to the list. */
41424fdd
RS
186
187static tree
188collect_iterators (exp, list)
189 tree exp, list;
190{
191 if (exp == 0) return list;
192
193 switch (TREE_CODE (exp))
194 {
195 case VAR_DECL:
196 if (! ITERATOR_P (exp) || ITERATOR_BOUND_P (exp))
197 return list;
198 if (value_member (exp, list))
199 return list;
200 return tree_cons (NULL_TREE, exp, list);
201
202 case TREE_LIST:
203 {
204 tree tail;
205 for (tail = exp; tail; tail = TREE_CHAIN (tail))
206 list = collect_iterators (TREE_VALUE (tail), list);
207 return list;
208 }
209
09aab2de
RS
210 case SAVE_EXPR:
211 /* In each scan, scan a given save_expr only once. */
93e4100a
RK
212 if (value_member (exp, save_exprs))
213 return list;
214
09aab2de
RS
215 save_exprs = tree_cons (NULL_TREE, exp, save_exprs);
216 return collect_iterators (TREE_OPERAND (exp, 0), list);
217
41424fdd
RS
218 /* we do not automatically iterate blocks -- one must */
219 /* use the FOR construct to do that */
220
221 case BLOCK:
222 return list;
223
224 default:
4c975d07 225 switch (TREE_CODE_CLASS (TREE_CODE (exp)))
41424fdd
RS
226 {
227 case '1':
03407c75
RK
228 return collect_iterators (TREE_OPERAND (exp, 0), list);
229
41424fdd
RS
230 case '2':
231 case '<':
03407c75
RK
232 return collect_iterators (TREE_OPERAND (exp, 0),
233 collect_iterators (TREE_OPERAND (exp, 1),
234 list));
235
41424fdd
RS
236 case 'e':
237 case 'r':
238 {
e4135fa5 239 int num_args = tree_code_length[(int) TREE_CODE (exp)];
41424fdd 240 int i;
4c975d07 241
03407c75
RK
242 /* Some tree codes have RTL, not trees, as operands. */
243 switch (TREE_CODE (exp))
244 {
03407c75
RK
245 case CALL_EXPR:
246 num_args = 2;
247 break;
248 case METHOD_CALL_EXPR:
249 num_args = 3;
250 break;
251 case WITH_CLEANUP_EXPR:
252 num_args = 1;
253 break;
254 case RTL_EXPR:
255 return list;
256 }
257
41424fdd
RS
258 for (i = 0; i < num_args; i++)
259 list = collect_iterators (TREE_OPERAND (exp, i), list);
260 return list;
261 }
4c975d07
RS
262 default:
263 return list;
41424fdd
RS
264 }
265 }
266}
267\f
268/* Emit rtl for the start of a loop for iterator IDECL.
269
270 If necessary, create loop counter rtx and store it as DECL_RTL of IDECL.
271
272 The prologue normally starts and ends with notes, which are returned
273 by this function in *START_NOTE and *END_NODE.
274 If START_NOTE and END_NODE are 0, we don't make those notes. */
275
276static void
277iterator_loop_prologue (idecl, start_note, end_note)
278 tree idecl;
279 rtx *start_note, *end_note;
280{
281 /* Force the save_expr in DECL_INITIAL to be calculated
282 if it hasn't been calculated yet. */
283 expand_expr (DECL_INITIAL (idecl), 0, VOIDmode, 0);
284
285 if (DECL_RTL (idecl) == 0)
286 expand_decl (idecl);
287
288 if (start_note)
289 *start_note = emit_note (0, NOTE_INSN_DELETED);
290 /* Initialize counter. */
4c975d07
RS
291 expand_expr (build (MODIFY_EXPR, TREE_TYPE (idecl),
292 idecl, integer_zero_node),
41424fdd
RS
293 0, VOIDmode, 0);
294
295 expand_start_loop_continue_elsewhere (1);
296
297 ITERATOR_BOUND_P (idecl) = 1;
298
299 if (end_note)
300 *end_note = emit_note (0, NOTE_INSN_DELETED);
301}
302
303/* Similar to the previous function, but for the end of the loop.
304
305 DECL_RTL is zeroed unless we are inside "({...})". The reason for that is
306 described below.
307
e26d4611
RS
308 When we create two (or more) loops based on the same IDECL, and
309 both inside the same "({...})" construct, we must be prepared to
310 delete both of the loops and create a single one on the level
311 above, i.e. enclosing the "({...})". The new loop has to use the
312 same counter rtl because the references to the iterator decl
313 (IDECL) have already been expanded as references to the counter
314 rtl.
41424fdd
RS
315
316 It is incorrect to use the same counter reg in different functions,
317 and it is desirable to use different counters in disjoint loops
e26d4611
RS
318 when we know there's no need to combine them (because then they can
319 get allocated separately). */
41424fdd
RS
320
321static void
322iterator_loop_epilogue (idecl, start_note, end_note)
323 tree idecl;
324 rtx *start_note, *end_note;
325{
326 tree test, incr;
327
328 if (start_note)
329 *start_note = emit_note (0, NOTE_INSN_DELETED);
330 expand_loop_continue_here ();
331 incr = build_binary_op (PLUS_EXPR, idecl, integer_one_node, 0);
4c975d07
RS
332 expand_expr (build (MODIFY_EXPR, TREE_TYPE (idecl), idecl, incr),
333 0, VOIDmode, 0);
41424fdd
RS
334 test = build_binary_op (LT_EXPR, idecl, DECL_INITIAL (idecl), 0);
335 expand_exit_loop_if_false (0, test);
336 expand_end_loop ();
337
338 ITERATOR_BOUND_P (idecl) = 0;
339 /* we can reset rtl since there is not chance that this expansion */
340 /* would be superceded by a higher level one */
341 if (top_level_ixpansion_p ())
342 DECL_RTL (idecl) = 0;
343 if (end_note)
344 *end_note = emit_note (0, NOTE_INSN_DELETED);
345}
346\f
e26d4611 347/* Return true if we are not currently inside a "({...})" construct. */
41424fdd
RS
348
349static int
350top_level_ixpansion_p ()
351{
352 return iter_stack == 0;
353}
354
355/* Given two chains of iter_stack_nodes,
356 append the nodes in X into Y. */
357
358static void
359isn_append (x, y)
360 struct iter_stack_node *x, *y;
361{
362 if (x->first == 0)
363 return;
364
365 if (y->first == 0)
366 {
367 y->first = x->first;
368 y->last = x->last;
369 }
370 else
371 {
372 y->last->next = x->first;
373 y->last = x->last;
374 }
375}
376
377/** Make X empty **/
378
379#define ISN_ZERO(X) (X).first=(X).last=0
380\f
381/* Move the ixpansions in sublevel_ixpansions into the current
382 node on the iter_stack, or discard them if the iter_stack is empty.
383 We do this at the end of a statement. */
384
385static void
386istack_sublevel_to_current ()
387{
388 /* At the top level we can throw away sublevel's expansions **/
389 /* because there is nobody above us to ask for a cleanup **/
390 if (iter_stack != 0)
391 /** Merging with empty sublevel list is a no-op **/
392 if (sublevel_ixpansions.last)
393 isn_append (&sublevel_ixpansions, iter_stack);
394
395 if (iter_stack == 0)
396 obstack_free (&ixp_obstack, ixp_firstobj);
397
398 ISN_ZERO (sublevel_ixpansions);
399}
400
401/* Push a new node on the iter_stack, when we enter a ({...}). */
402
403void
404push_iterator_stack ()
405{
406 struct iter_stack_node *new_top
407 = (struct iter_stack_node*)
408 obstack_alloc (&ixp_obstack, sizeof (struct iter_stack_node));
409
410 new_top->first = 0;
411 new_top->last = 0;
412 new_top->next = iter_stack;
413 iter_stack = new_top;
414}
415
416/* Pop iter_stack, moving the ixpansions in the node being popped
417 into sublevel_ixpansions. */
418
419void
420pop_iterator_stack ()
421{
422 if (iter_stack == 0)
423 abort ();
424
425 isn_append (iter_stack, &sublevel_ixpansions);
426 /** Pop current level node: */
427 iter_stack = iter_stack->next;
428}
429\f
430
431/* Record an iterator expansion ("ixpansion") for IDECL.
432 The remaining paramters are the notes in the loop entry
433 and exit rtl. */
434
435static void
436add_ixpansion (idecl, pro_start, pro_end, epi_start, epi_end)
437 tree idecl;
438 rtx pro_start, pro_end, epi_start, epi_end;
439{
440 struct ixpansion* newix;
441
442 /* Do nothing if we are not inside "({...})",
443 as in that case this expansion can't need subsequent RTL modification. */
444 if (iter_stack == 0)
445 return;
446
447 newix = (struct ixpansion*) obstack_alloc (&ixp_obstack,
448 sizeof (struct ixpansion));
449 newix->ixdecl = idecl;
450 newix->ixprologue_start = pro_start;
451 newix->ixprologue_end = pro_end;
452 newix->ixepilogue_start = epi_start;
453 newix->ixepilogue_end = epi_end;
454
455 newix->next = iter_stack->first;
456 iter_stack->first = newix;
457 if (iter_stack->last == 0)
458 iter_stack->last = newix;
459}
460
461/* Delete the RTL for all ixpansions for iterator IDECL
462 in our sublevels. We do this when we make a larger
463 containing expansion for IDECL. */
464
465static void
466delete_ixpansion (idecl)
467 tree idecl;
468{
469 struct ixpansion* previx = 0, *ix;
470
471 for (ix = sublevel_ixpansions.first; ix; ix = ix->next)
472 if (ix->ixdecl == idecl)
473 {
474 /** zero means that this is a mark for FOR -- **/
475 /** we do not delete anything, just issue an error. **/
476
477 if (ix->ixprologue_start == 0)
478 error_with_decl (idecl,
4c975d07 479 "`for (%s)' appears within implicit iteration");
41424fdd
RS
480 else
481 {
482 rtx insn;
483 /* We delete all insns, including notes because leaving loop */
484 /* notes and barriers produced by iterator expansion would */
485 /* be misleading to other phases */
486
487 for (insn = NEXT_INSN (ix->ixprologue_start);
488 insn != ix->ixprologue_end;
489 insn = NEXT_INSN (insn))
490 delete_insn (insn);
491 for (insn = NEXT_INSN (ix->ixepilogue_start);
492 insn != ix->ixepilogue_end;
493 insn = NEXT_INSN (insn))
494 delete_insn (insn);
495 }
496
497 /* Delete this ixpansion from sublevel_ixpansions. */
498 if (previx)
499 previx->next = ix->next;
500 else
501 sublevel_ixpansions.first = ix->next;
502 if (sublevel_ixpansions.last == ix)
503 sublevel_ixpansions.last = previx;
504 }
505 else
506 previx = ix;
507}
508\f
41424fdd
RS
509#ifdef DEBUG_ITERATORS
510
e26d4611
RS
511/* The functions below are for use from source level debugger.
512 They print short forms of iterator lists and the iterator stack. */
513
514/* Print the name of the iterator D. */
41424fdd 515
41424fdd 516void
e26d4611
RS
517prdecl (d)
518 tree d;
41424fdd 519{
e26d4611 520 if (d)
41424fdd 521 {
e26d4611 522 if (TREE_CODE (d) == VAR_DECL)
41424fdd 523 {
e26d4611 524 tree tname = DECL_NAME (d);
41424fdd
RS
525 char *dname = IDENTIFIER_POINTER (tname);
526 fprintf (stderr, dname);
527 }
528 else
529 fprintf (stderr, "<<Not a Decl!!!>>");
530 }
531 else
532 fprintf (stderr, "<<NULL!!>>");
533}
534
535/* Print Iterator List -- names only */
536
537tree
538pil (head)
539 tree head;
540{
541 tree current, next;
e26d4611 542 for (current = head; current; current = next)
41424fdd
RS
543 {
544 tree node = TREE_VALUE (current);
e26d4611 545 prdecl (node);
41424fdd
RS
546 next = TREE_CHAIN (current);
547 if (next) fprintf (stderr, ",");
548 }
549 fprintf (stderr, "\n");
550}
551
552/* Print IXpansion List */
553
554struct ixpansion *
555pixl (head)
556 struct ixpansion *head;
557{
558 struct ixpansion *current, *next;
559 fprintf (stderr, "> ");
560 if (head == 0)
561 fprintf (stderr, "(empty)");
562
563 for (current=head; current; current = next)
564 {
565 tree node = current->ixdecl;
e26d4611 566 prdecl (node);
41424fdd
RS
567 next = current->next;
568 if (next)
569 fprintf (stderr, ",");
570 }
571 fprintf (stderr, "\n");
572 return head;
573}
574
575/* Print Iterator Stack*/
576
577void
578pis ()
579{
580 struct iter_stack_node *stack_node;
581
582 fprintf (stderr, "--SubLevel: ");
583 pixl (sublevel_ixpansions.first);
584 fprintf (stderr, "--Stack:--\n");
585 for (stack_node = iter_stack;
586 stack_node;
587 stack_node = stack_node->next)
588 pixl (stack_node->first);
589}
e26d4611
RS
590
591#endif /* DEBUG_ITERATORS */
This page took 0.114243 seconds and 5 git commands to generate.