OSDN Git Service

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