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