1 /* Implement looping actions for CHILL.
2 Copyright (C) 1992, 1993, 1994, 2000
3 Free Software Foundation, Inc.
5 This file is part of GNU CC.
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)
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.
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. */
35 /* if the user codes '-flocal-loop-counter' on the command line,
36 ch-actions.c (lang_decode_option) will set this flag. */
37 int flag_local_loop_counter
= 0;
39 extern tree chill_truthvalue_conversion
PARAMS ((tree
));
40 extern rtx emit_line_note
PARAMS ((char *, int));
41 extern void error
PARAMS ((char *, ...));
42 extern rtx expand_assignment
PARAMS ((tree
, tree
, int, int));
43 extern void save_expr_under_name
PARAMS ((tree
, tree
));
44 extern void stamp_nesting_label
PARAMS ((tree
));
45 extern int int_fits_type_p
PARAMS ((tree
, tree
));
46 extern void warning
PARAMS ((char *, ...));
48 /* forward declarations */
49 static int classify_loop
PARAMS ((void));
50 static int declare_temps
PARAMS ((void));
51 static int initialize_iter_var
PARAMS ((void));
52 static int maybe_skip_loop
PARAMS ((void));
53 static int top_loop_end_check
PARAMS ((void));
54 static int bottom_loop_end_check
PARAMS ((void));
55 static int increment_temps
PARAMS ((void));
56 static tree build_temporary_variable
PARAMS ((char *, tree
));
57 static tree maybe_make_for_temp
PARAMS ((tree
, char *, tree
));
58 static tree chill_unsigned_type
PARAMS ((tree
));
60 /* In terms of the parameters passed to build_loop_iterator,
61 * there are several types of loops. They are encoded by
62 * the ITER_TYPE enumeration.
64 * 1) DO FOR EVER; ... OD
65 * indicated by a NULL_TREE start_exp, step_exp and end_exp,
66 * condition == NULL, in_flag = 0, and ever_flag == 1 in the
69 * 2) DO WHILE cond; ... OD
70 * indicated by NULL_TREE start_exp, step_exp and end_exp,
71 * in_flag = 0, and condition != NULL.
74 * indicated by NULL_TREEs in start_exp, step_exp and end_exp,
75 * condition != NULL, in_flag == 0 and ever_flag == 0. This
76 * is not really a loop, but a compound statement.
78 * 4) DO FOR user_var := start_exp
79 * [DOWN] TO end_exp BY step_exp; ... DO
80 * indicated by non-NULL_TREE start_exp, step_exp and end_exp.
82 * 5) DO FOR user_var [DOWN] IN discrete_mode; ... OD
83 * indicated by in_flag == 1. start_exp is a non-NULL_TREE
84 * discrete mode, with an optional down_flag.
86 * 6) DO FOR user_var [DOWN] IN powerset_expr; ... OD
87 * indicated by in_flag == 1. start_exp is a non-NULL_TREE
88 * powerset mode, with an optional down_flag.
90 * 7) DO FOR user_var [DOWN] IN location; ... OD
91 * indicated by in_flag == 1. start_exp is a non-NULL_TREE
92 * location mode, with an optional down_flag.
108 typedef struct iterator
110 /* These variables only have meaning in the first ITERATOR structure. */
111 ITER_TYPE itype
; /* type of this iterator */
112 int error_flag
; /* TRUE if no loop was started due to
114 tree condition
; /* WHILE condition expression */
115 int down_flag
; /* TRUE if DOWN was coded */
117 /* These variables have meaning in every ITERATOR structure. */
118 tree user_var
; /* user's explicit iteration variable */
119 tree start_exp
; /* user's start expression
120 or IN expression of a FOR .. IN*/
121 tree step_exp
; /* user's step expression */
122 tree end_exp
; /* user's end expression */
123 tree start_temp
; /* temp holding evaluated start_exp */
124 tree end_temp
; /* temp holding evaluated end_exp */
125 tree step_temp
; /* temp holding evaluated step_exp */
126 tree powerset_temp
; /* temp holding user's initial powerset expression */
127 tree loc_ptr_temp
; /* temp holding count for LOC enumeration ptr */
128 tree iter_var
; /* hidden variable for the loop */
129 tree iter_type
; /* hidden variable's type */
130 tree base_type
; /* LOC enumeration base type */
131 struct iterator
*next
; /* ptr to next iterator for this loop */
135 * There's an entry like this for each nested DO loop.
136 * The list is maintained by push_loop_block
137 * and pop_loop_block.
139 typedef struct loop
{
140 struct loop
*nxt_level
; /* pointer to enclosing loop */
141 ITERATOR
*iter_list
; /* iterators for the current loop */
144 static LOOP
*loop_stack
= (LOOP
*)0;
148 Here is a CHILL DO FOR statement:
150 DO FOR user_var := start_exp BY step_exp [DOWN] TO end_exp
153 For this loop to be 'safe', like a Pascal FOR loop, the start,
154 end, and increment expressions are computed once, before the
155 assignment to the iteration variable and saved in temporaries,
156 before the first assignment of the iteration variable, so the
159 FOR i := (i+1) TO (i+10) DO
161 To prevent changes to the start/end/step expressions from
162 effecting the loop's termination, and to make the loop end-check
163 as simple as possible, we evaluate the step expression into
164 a temporary and compute a hidden iteration count before entering
165 the loop's body. User code cannot effect the counter, and the
166 end-loop check simply decrements the counter and checks for zero.
168 The whole phrase FOR iter := ... TO end_exp can be repeated
169 multiple times, with different user-iteration variables. This
172 The loop counter calculations need careful design since a loop
173 from MININT TO MAXINT must work, in the precision of integers.
175 Here's how it works, in C:
177 0) The DO ... OD loop is simply a block with
180 1) The DO FOR EVER is simply implemented:
189 2) The DO WHILE is also simple:
193 if (!condition) goto end_loop
201 3) The DO FOR [while condition] loop (no DOWN)
207 start_temp = start_exp
209 if (end_exp < start_exp) goto end_loop
210 // following line is all unsigned arithmetic
211 iter_var = (end_exp - start_exp + step_exp) / step_exp
212 user_var = start_temp
214 if (!condition) goto end_loop
219 if (iter_var == 0) goto end_loop
220 user_var += step_temp
225 4) The proposed CHILL for [while condition] loop (with DOWN)
230 start_temp = start_exp
232 if (end_exp > start_exp) goto end_loop
233 // following line is all unsigned arithmetic
234 iter_var = (start_exp - end_exp + step_exp) / step_exp
235 user_var = start_temp
237 if (!condition) goto end_loop
242 if (iter_var == 0) goto end_loop
243 user_var -= step_temp
249 5) The range loop, which iterates over a mode's possible
250 values, works just like the above step loops, but with
251 the start and end values taken from the mode's lower
252 and upper domain values.
255 6) The FOR IN loop, where a location enumeration is
256 specified (see spec on page 81 of Z.200, bottom
260 decl iter_var as an unsigned integer
261 loc_ptr_temp as pointer to a composite base type
264 iter_var = array's length field
266 iter_var = sizeof array / sizeof base_type
267 loc_ptr_temp = &of highest or lowest indexable entry
269 if (!condition) goto end_loop
274 if (iter_var == 0) goto end_loop
275 loc_ptr_temp +/-= sizeof array base_type
280 7) The DO FOR (DOWN) IN powerset_exp
284 decl iterator as basetype of powerset
286 powerset_temp := start_exp
289 if (__flsetclrpowerset () == 0) goto end_loop;
291 if (__ffsetclrpowerset () == 0) goto end_loop;
292 if (!condition) goto end_loop
301 So, here's the general DO FOR schema, as implemented here:
303 classify_loop -- what type of loop have we?
304 -- build_iterator does some of this, also
305 expand_start_loop -- start the loop's control scope
306 -- start scope for synthesized loop variables
307 declare_temps -- create, initialize temporary variables
308 maybe_skip_loop -- skip loop if end conditions unsatisfiable
309 initialize_iter_var -- initialize the iteration counter
310 -- initialize user's loop variable
311 expand_start_loop -- generate top-of-loop label
312 top_loop_end_check -- generate while code and/or
313 powerset find-a-bit function call
316 . user's loop body code
319 bottom_loop_end_check -- exit if counter has become zero
320 increment_temps -- update temps for next iteration
321 expand_end_loop -- generate jump back to top of loop
322 expand_end_cond -- generate label for end of conditional
323 -- end of scope for synthesized loop variables
324 free_iterators -- free up iterator space
326 When there are two or more iterator phrases, each of the
327 above loop steps must act upon all iterators. For example,
328 the 'increment_temps' step must increment all temporaries
329 (associated with all iterators).
331 NOTE: Z.200, section 10.1 says that a block is ...
332 "the actions statement list in a do action, including any
333 loop counter and while control". This means that an exp-
334 ression in a WHILE control can include references to the
335 loop counters created for the loop's exclusive use.
340 DO FOR j IN a WHILE j > 0;
343 The 'j' referenced in the while is the loc-identity 'j'
344 created inside the loop's scope, and NOT the 'j' declared
349 * The following routines are called directly by the
355 LOOP
*temp
= (LOOP
*)xmalloc (sizeof (LOOP
));
357 /* push a new loop onto the stack */
358 temp
->nxt_level
= loop_stack
;
359 temp
->iter_list
= (ITERATOR
*)0;
366 LOOP
*do_temp
= loop_stack
;
369 /* pop loop block off the list */
370 loop_stack
= do_temp
->nxt_level
;
372 /* free the loop's iterator blocks */
373 ip
= do_temp
->iter_list
;
376 ITERATOR
*temp
= ip
->next
;
386 ITERATOR
*firstp
= loop_stack
->iter_list
;
392 * We need to classify the loop and declare its temporaries
393 * here, so as to define them before the WHILE condition
394 * (if any) is parsed. The WHILE expression may refer to
397 if (classify_loop ())
400 if (firstp
->itype
!= DO_OD
)
405 expand_start_bindings (0);
410 end_loop_scope (opt_label
)
414 possibly_define_exit_label (opt_label
);
420 expand_end_bindings (getdecls (), kept_level_p (), 0);
424 /* The iterator structure records all aspects of a
425 * 'FOR i := start [DOWN] TO end' clause or
426 * 'FOR i IN modename' or 'FOR i IN powerset' clause.
427 * It's saved on the iter_list of the current LOOP.
430 build_loop_iterator (user_var
, start_exp
, step_exp
, end_exp
,
431 down_flag
, in_flag
, ever_flag
)
432 tree user_var
, start_exp
, step_exp
, end_exp
;
433 int down_flag
, in_flag
, ever_flag
;
435 ITERATOR
*ip
= (ITERATOR
*)xmalloc (sizeof (ITERATOR
));
437 /* chain this iterator onto the current loop */
438 if (loop_stack
->iter_list
== NULL
)
439 loop_stack
->iter_list
= ip
;
442 ITERATOR
*temp
= loop_stack
->iter_list
;
443 while (temp
->next
!= NULL
)
448 ip
->itype
= DO_UNUSED
;
449 ip
->user_var
= user_var
;
450 ip
->start_exp
= start_exp
;
451 ip
->step_exp
= step_exp
;
452 ip
->end_exp
= end_exp
;
453 ip
->condition
= NULL_TREE
;
454 ip
->start_temp
= NULL_TREE
;
455 ip
->end_temp
= NULL_TREE
;
456 ip
->step_temp
= NULL_TREE
;
457 ip
->down_flag
= down_flag
;
458 ip
->powerset_temp
= NULL_TREE
;
459 ip
->iter_var
= NULL_TREE
;
460 ip
->iter_type
= NULL_TREE
;
461 ip
->loc_ptr_temp
= NULL_TREE
;
462 ip
->error_flag
= 1; /* assume error will be found */
463 ip
->next
= (ITERATOR
*)0;
466 ip
->itype
= DO_FOREVER
;
467 else if (in_flag
&& start_exp
!= NULL_TREE
)
469 if (TREE_CODE (start_exp
) == ERROR_MARK
)
471 if (TREE_CODE (TREE_TYPE (start_exp
)) == SET_TYPE
)
472 ip
->itype
= DO_POWERSET
;
473 else if (discrete_type_p (TREE_TYPE (ip
->start_exp
)))
474 ip
->itype
= DO_RANGE
;
475 else if (TREE_CODE (TREE_TYPE (ip
->start_exp
)) == ARRAY_TYPE
)
477 else if (chill_varying_type_p (TREE_TYPE (ip
->start_exp
)))
478 ip
->itype
= DO_LOC_VARYING
;
481 error ("loop's IN expression is not a composite object");
485 else if (start_exp
== NULL_TREE
&& end_exp
== NULL_TREE
486 && step_exp
== NULL_TREE
&& !down_flag
)
490 /* FIXME: Move this to the lexer? */
491 #define CST_FITS_INT(NODE) (TREE_CODE(NODE) == INTEGER_CST &&\
492 int_fits_type_p (NODE, integer_type_node))
494 tree max_prec_type
= integer_type_node
;
496 if (! discrete_type_p (TREE_TYPE (ip
->start_exp
)))
498 error ("start expr must have discrete mode");
501 if (TREE_CODE (TREE_TYPE (ip
->start_exp
)) == ENUMERAL_TYPE
502 && CH_ENUM_IS_NUMBERED (TREE_TYPE (ip
->start_exp
)))
504 error ("DO FOR start expression is a numbered SET");
507 if (TREE_CODE (TREE_TYPE (ip
->end_exp
)) == ENUMERAL_TYPE
508 && CH_ENUM_IS_NUMBERED (TREE_TYPE (ip
->end_exp
)))
510 error ("TO expression is a numbered SET");
513 /* Convert all three expressions to a common precision,
514 which is the largest precision they exhibit, but
515 INTEGER_CST nodes are built in the lexer as
516 long_integer_type nodes. We'll treat convert them to
517 integer_type_nodes if possible, for faster loop times. */
519 if (TYPE_PRECISION (max_prec_type
) <
520 TYPE_PRECISION (TREE_TYPE (ip
->start_exp
))
521 && !CST_FITS_INT (ip
->start_exp
))
522 max_prec_type
= TREE_TYPE (ip
->start_exp
);
523 if (! discrete_type_p (TREE_TYPE (ip
->end_exp
)))
525 error ("TO expr must have discrete mode");
528 if (! CH_COMPATIBLE (ip
->start_exp
,
529 TREE_TYPE (ip
->end_exp
)))
531 error ("start expr and TO expr must be compatible");
534 if (TYPE_PRECISION (max_prec_type
) <
535 TYPE_PRECISION (TREE_TYPE (ip
->end_exp
))
536 && !CST_FITS_INT (ip
->end_exp
))
537 max_prec_type
= TREE_TYPE (ip
->end_exp
);
538 if (ip
->step_exp
!= NULL_TREE
)
540 /* assure that default 'BY 1' gets a useful type */
541 if (ip
->step_exp
== integer_one_node
)
542 ip
->step_exp
= convert (TREE_TYPE (ip
->start_exp
),
544 if (! discrete_type_p (TREE_TYPE (ip
->step_exp
)))
546 error ("BY expr must have discrete mode");
549 if (! CH_COMPATIBLE (ip
->start_exp
,
550 TREE_TYPE (ip
->step_exp
)))
552 error ("start expr and BY expr must be compatible");
555 if (TYPE_PRECISION (max_prec_type
) <
556 TYPE_PRECISION (TREE_TYPE (ip
->step_exp
))
557 && !CST_FITS_INT (ip
->step_exp
))
558 max_prec_type
= TREE_TYPE (ip
->step_exp
);
560 if (TREE_CODE (ip
->start_exp
) == INTEGER_CST
561 && TREE_CODE (ip
->end_exp
) == INTEGER_CST
562 && compare_int_csts (ip
->down_flag
? LT_EXPR
: GT_EXPR
,
563 ip
->start_exp
, ip
->end_exp
))
564 warning ("body of DO FOR will never execute");
567 convert (max_prec_type
, ip
->start_exp
);
569 convert (max_prec_type
, ip
->end_exp
);
571 if (ip
->step_exp
!= NULL_TREE
)
574 convert (max_prec_type
, ip
->step_exp
);
576 if (TREE_CODE (ip
->step_exp
) != INTEGER_CST
)
578 /* generate runtime check for negative BY expr */
580 check_range (ip
->step_exp
, ip
->step_exp
,
581 integer_zero_node
, NULL_TREE
);
583 else if (compare_int_csts (LE_EXPR
, ip
->step_exp
, integer_zero_node
))
585 error ("BY expression is negative or zero");
592 ip
->error_flag
= 0; /* no errors! */
596 build_loop_start (while_control
, start_label
)
597 tree while_control
, start_label
;
599 ITERATOR
*firstp
= loop_stack
->iter_list
;
601 firstp
->condition
= while_control
;
603 if (firstp
->error_flag
)
606 /* We didn't know at begin_loop_scope time about the condition;
607 adjust iterator type now. */
608 if (firstp
->itype
== DO_OD
&& firstp
->condition
)
609 firstp
->itype
= DO_WHILE
;
611 if (initialize_iter_var ())
614 if (maybe_skip_loop ())
617 /* use the label as an 'exit' label,
618 'goto' needs another sort of label */
619 expand_start_loop (start_label
!= NULL_TREE
);
621 if (top_loop_end_check ())
623 emit_line_note (input_filename
, lineno
);
627 * Called after the last action of the loop body
633 ITERATOR
*ip
= loop_stack
->iter_list
;
635 emit_line_note (input_filename
, lineno
);
640 if (bottom_loop_end_check ())
643 if (increment_temps ())
646 if (ip
->itype
!= DO_OD
)
650 for (; ip
!= NULL
; ip
= ip
->next
)
666 * The rest of the routines in this file are called from
667 * the above three routines.
672 ITERATOR
*firstp
= loop_stack
->iter_list
, *ip
;
674 firstp
->error_flag
= 0;
675 if (firstp
->itype
== DO_UNUSED
|| firstp
->itype
== DO_OD
)
677 /* if we have just DO .. OD, do nothing - this is just a
678 BEGIN .. END without creating a new scope, and no looping */
679 if (firstp
->condition
!= NULL_TREE
)
680 firstp
->itype
= DO_WHILE
;
682 firstp
->itype
= DO_OD
;
685 /* Issue a warning if the any loop counter is mentioned more
686 than once in the iterator list. */
687 for (ip
= firstp
; ip
!= NULL
; ip
= ip
->next
)
699 /* FIXME: check for name uniqueness */
705 return firstp
->error_flag
;
709 * Reserve space for any loop-control temporaries, initialize them
714 ITERATOR
*firstp
= loop_stack
->iter_list
, *ip
;
717 for (ip
= firstp
; ip
!= NULL
; ip
= ip
->next
)
725 ip
->iter_type
= chill_unsigned_type (TREE_TYPE (ip
->start_exp
));
727 /* create, initialize temporaries if expressions aren't constant */
728 ip
->start_temp
= maybe_make_for_temp (ip
->start_exp
, "for_start",
730 ip
->end_temp
= maybe_make_for_temp (ip
->end_exp
, "for_end",
732 /* this is just the step-expression */
733 ip
->step_temp
= maybe_make_for_temp (ip
->step_exp
, "for_step",
738 ip
->iter_type
= chill_unsigned_type_node
;
741 (ip
->down_flag
? build_chill_upper
: build_chill_lower
)(TREE_TYPE (ip
->start_exp
));
743 (ip
->down_flag
? build_chill_lower
: build_chill_upper
)(TREE_TYPE (ip
->start_exp
));
745 ip
->step_temp
= integer_one_node
;
748 if (flag_local_loop_counter
)
750 /* (re-)declare the user's iteration variable in the
752 tree id_node
= ip
->user_var
;
753 IDENTIFIER_LOCAL_VALUE (id_node
) = ip
->user_var
=
754 decl_temp1 (id_node
, ip
->iter_type
, 0, NULL_TREE
,
759 /* in this case, it's a previously-declared
760 VAR_DECL node, checked in build_loop_iterator. */
761 if (TREE_CODE (ip
->user_var
) == IDENTIFIER_NODE
)
762 ip
->user_var
= lookup_name (ip
->user_var
);
763 if (ip
->user_var
== NULL_TREE
)
765 error ("loop identifier undeclared");
771 decl_temp1 (get_unique_identifier ("iter_var"),
772 ip
->iter_type
, 0, NULL_TREE
, 0, 0);
776 ip
->iter_type
= chill_unsigned_type (
777 TYPE_DOMAIN (TREE_TYPE (ip
->start_exp
)));
778 if (flag_local_loop_counter
)
780 /* declare the user's iteration variable in the loop's scope. */
781 /* in this case, it's just an IDENTIFIER_NODE */
783 decl_temp1 (ip
->user_var
, ip
->iter_type
, 0, NULL_TREE
, 0, 0);
787 /* in this case, it's a previously-declared VAR_DECL node */
788 ip
->user_var
= lookup_name (ip
->user_var
);
790 /* the user's powerset-expression, evaluated and saved in a temp */
791 ip
->powerset_temp
= maybe_make_for_temp (ip
->start_exp
, "for_set",
792 TREE_TYPE (ip
->start_exp
));
793 mark_addressable (ip
->powerset_temp
);
798 ip
->iter_type
= chill_unsigned_type_node
;
799 /* create the counter temp */
801 build_temporary_variable ("iter_var", ip
->iter_type
);
803 if (!CH_LOCATION_P (ip
->start_exp
))
805 = decl_temp1 (get_unique_identifier ("iter_loc"),
806 TREE_TYPE (ip
->start_exp
), 0,
807 ip
->start_exp
, 0, 0);
809 if (ip
->itype
== DO_LOC
)
811 tree array_type
= TREE_TYPE (ip
->start_exp
);
815 if (TREE_CODE (TREE_TYPE (array_type
)) == BOOLEAN_TYPE
)
817 error ("can't iterate through array of BOOL");
819 return ip
->error_flag
;
822 /* FIXME: check for array type in ip->start_exp */
824 /* create pointer temporary */
825 ip
->base_type
= TREE_TYPE (array_type
);
826 ptr_type
= build_pointer_type (ip
->base_type
);
828 build_temporary_variable ("loc_ptr_tmp", ptr_type
);
830 /* declare the user's iteration variable in
831 the loop's scope, as an expression, to be
832 passed to build_component_ref later */
833 save_expr_under_name (ip
->user_var
,
834 build1 (INDIRECT_REF
, ip
->base_type
,
837 /* FIXME: see stor_layout */
838 ip
->step_temp
= size_in_bytes (ip
->base_type
);
840 temp
= TYPE_DOMAIN (array_type
);
842 /* pointer to first array entry to look at */
843 start_ptr
= build1 (ADDR_EXPR
, ptr_type
, ip
->start_exp
);
844 mark_addressable (ip
->start_exp
);
845 ip
->start_temp
= ip
->down_flag
?
846 fold (build (PLUS_EXPR
, ptr_type
,
848 fold (build (MULT_EXPR
, integer_type_node
, ip
->step_temp
,
849 fold (build (MINUS_EXPR
, integer_type_node
,
850 TYPE_MAX_VALUE (temp
),
851 TYPE_MIN_VALUE (temp
)))))))
857 convert (integer_type_node
,
858 build_component_ref (ip
->start_exp
, var_length_id
));
859 tree array_type
= TREE_TYPE (TREE_CHAIN (
860 TYPE_FIELDS (TREE_TYPE (ip
->start_exp
))));
861 tree array_data_ptr
=
862 build_component_ref (ip
->start_exp
, var_data_id
);
865 if (TREE_CODE (TREE_TYPE (array_type
)) == BOOLEAN_TYPE
)
867 error ("Can't iterate through array of BOOL");
868 firstp
->error_flag
= 1;
869 return firstp
->error_flag
;
872 /* create pointer temporary */
873 ip
->base_type
= TREE_TYPE (array_type
);
874 ptr_type
= build_pointer_type (ip
->base_type
);
876 build_temporary_variable ("loc_ptr_temp", ptr_type
);
879 /* declare the user's iteration variable in
880 the loop's scope, as an expression, to be
881 passed to build_component_ref later */
882 save_expr_under_name (ip
->user_var
,
883 build1 (INDIRECT_REF
, ip
->base_type
,
886 /* FIXME: see stor_layout */
887 ip
->step_temp
= size_in_bytes (ip
->base_type
);
889 /* pointer to first array entry to look at */
890 start_ptr
= build1 (ADDR_EXPR
, ptr_type
, array_data_ptr
);
891 mark_addressable (array_data_ptr
);
892 ip
->start_temp
= ip
->down_flag
?
893 fold (build (PLUS_EXPR
, ptr_type
,
895 fold (build (MULT_EXPR
, integer_type_node
, ip
->step_temp
,
896 fold (build (MINUS_EXPR
, integer_type_node
,
898 integer_one_node
))))))
905 return firstp
->error_flag
;
909 * Initialize the hidden iteration-control variables,
910 * and the user's explicit loop variable.
913 initialize_iter_var ()
915 ITERATOR
*firstp
= loop_stack
->iter_list
, *ip
;
917 for (ip
= firstp
; ip
!= NULL
; ip
= ip
->next
)
928 fold (build (PLUS_EXPR
, ip
->iter_type
, integer_one_node
,
929 fold (build (TRUNC_DIV_EXPR
, ip
->iter_type
,
930 convert (ip
->iter_type
,
931 fold (build (MINUS_EXPR
, ip
->iter_type
,
932 ip
->down_flag
? ip
->start_temp
: ip
->end_temp
,
933 ip
->down_flag
? ip
->end_temp
: ip
->start_temp
))),
935 /* initialize the loop's hidden counter variable */
937 build_chill_modify_expr (ip
->iter_var
, count
));
939 /* initialize user's variable */
941 build_chill_modify_expr (ip
->user_var
, ip
->start_temp
));
948 tree array_type
= TREE_TYPE (ip
->start_exp
);
950 fold (build (TRUNC_DIV_EXPR
, integer_type_node
,
951 size_in_bytes (array_type
),
952 size_in_bytes (TREE_TYPE (array_type
))));
955 build_chill_modify_expr (ip
->iter_var
, array_length
));
961 build_chill_modify_expr (ip
->iter_var
,
962 convert (integer_type_node
,
963 build_component_ref (ip
->start_exp
, var_length_id
))));
967 build_chill_modify_expr (ip
->loc_ptr_temp
,
975 return firstp
->error_flag
;
978 /* Generate code to skip the whole loop, if start expression not
979 * <= end expression (or >= for DOWN loops). This comparison must
980 * *NOT* be done in unsigned mode, or it will fail.
981 * Also, skip processing an empty VARYING array.
986 ITERATOR
*firstp
= loop_stack
->iter_list
, *ip
;
988 for (ip
= firstp
; ip
!= NULL
; ip
= ip
->next
)
994 build (ip
->down_flag
? GE_EXPR
: LE_EXPR
,
995 TREE_TYPE (ip
->start_exp
),
996 ip
->start_exp
, ip
->end_exp
), 0);
1000 { tree array_length
=
1001 convert (integer_type_node
,
1002 build_component_ref (ip
->start_exp
, var_length_id
));
1004 build (NE_EXPR
, TREE_TYPE (array_length
),
1005 array_length
, integer_zero_node
), 0);
1016 * Check at the top of the loop for a termination
1019 top_loop_end_check ()
1021 ITERATOR
*firstp
= loop_stack
->iter_list
, *ip
;
1023 /* now, exit the loop if the condition isn't TRUE. */
1024 if (firstp
->condition
)
1026 expand_exit_loop_if_false (0,
1027 chill_truthvalue_conversion (firstp
->condition
));
1030 for (ip
= firstp
; ip
!= NULL
; ip
= ip
->next
)
1045 func_name
= "__flsetclrpowerset";
1047 func_name
= "__ffsetclrpowerset";
1049 temp1
= TYPE_MIN_VALUE
1050 (TYPE_DOMAIN (TREE_TYPE (ip
->powerset_temp
)));
1051 expand_exit_loop_if_false (0,
1052 build_chill_function_call (lookup_name (get_identifier (func_name
)),
1053 tree_cons (NULL_TREE
, force_addr_of (ip
->powerset_temp
),
1054 tree_cons (NULL_TREE
, powersetlen (ip
->powerset_temp
),
1055 tree_cons (NULL_TREE
, force_addr_of (ip
->user_var
),
1056 tree_cons (NULL_TREE
, size_in_bytes (TREE_TYPE (ip
->user_var
)),
1057 tree_cons (NULL_TREE
,
1058 convert (long_integer_type_node
, temp1
),
1063 case DO_LOC_VARYING
:
1069 return firstp
->error_flag
;
1073 * Check generated temporaries for loop's end
1076 bottom_loop_end_check ()
1078 ITERATOR
*firstp
= loop_stack
->iter_list
, *ip
;
1080 emit_line_note (input_filename
, lineno
);
1082 /* now, generate code to check each loop counter for termination */
1083 for (ip
= firstp
; ip
!= NULL
; ip
= ip
->next
)
1093 case DO_LOC_VARYING
:
1094 /* decrement iteration counter by one */
1095 chill_expand_assignment (ip
->iter_var
, MINUS_EXPR
, integer_one_node
);
1096 /* exit if it's zero */
1097 expand_exit_loop_if_false (0,
1098 build (NE_EXPR
, boolean_type_node
,
1100 integer_zero_node
));
1109 return firstp
->error_flag
;
1113 * increment the loop-control variables.
1118 ITERATOR
*firstp
= loop_stack
->iter_list
, *ip
;
1120 for (ip
= firstp
; ip
!= NULL
; ip
= ip
->next
)
1131 fold (build (ip
->down_flag
? MINUS_EXPR
: PLUS_EXPR
,
1132 TREE_TYPE (ip
->user_var
), ip
->user_var
,
1135 build_chill_modify_expr (ip
->user_var
, delta
));
1139 case DO_LOC_VARYING
:
1140 /* This statement uses the C semantics, so that
1141 the pointer is actually incremented by the
1142 length of the object pointed to. */
1145 build_modify_expr (ip
->loc_ptr_temp
,
1146 ip
->down_flag
? MINUS_EXPR
: PLUS_EXPR
,
1150 enum tree_code op
= ip
->down_flag
? MINUS_EXPR
: PLUS_EXPR
;
1151 tree el_type
= TREE_TYPE (TREE_TYPE (ip
->loc_ptr_temp
));
1152 chill_expand_assignment (ip
->loc_ptr_temp
, NOP_EXPR
,
1154 TREE_TYPE (ip
->loc_ptr_temp
),
1156 size_in_bytes (el_type
)));
1166 return firstp
->error_flag
;
1170 * Generate a (temporary) unique identifier_node of
1171 * the form "__tmp_%s_%d"
1174 get_unique_identifier (lead
)
1178 static int idcount
= 0;
1180 sprintf (idbuf
, "__tmp_%s_%d", lead
? lead
: "", idcount
++);
1181 return get_identifier (idbuf
);
1185 * build a temporary variable, given its NAME and TYPE.
1186 * The name will have a number appended to assure uniqueness.
1187 * return its DECL node.
1190 build_temporary_variable (name
, type
)
1194 return decl_temp1 (get_unique_identifier (name
), type
, 0, NULL_TREE
, 0, 0);
1199 * If the given expression isn't a constant, build a temp for it
1200 * and evaluate the expression into the temp. Return the tree
1201 * representing either the original constant expression or the
1202 * temp which now contains the expression's value.
1205 maybe_make_for_temp (exp
, temp_name
, exp_type
)
1212 if (exp
!= NULL_TREE
)
1214 /* if exp isn't constant, create a temporary for its value */
1215 if (TREE_CONSTANT (exp
))
1217 /* FIXME: assure that TREE_TYPE (result) == ip->exp_type */
1218 result
= convert (exp_type
, exp
);
1221 /* build temp, assign the value */
1222 result
= decl_temp1 (get_unique_identifier (temp_name
), exp_type
, 0,
1231 * Adapt the C unsigned_type function to CHILL - we need to
1232 * account for any CHILL-specific integer types here. So far,
1233 * the 16-bit integer type is the only one.
1236 chill_unsigned_type (type
)
1239 extern tree chill_unsigned_type_node
;
1240 tree type1
= TYPE_MAIN_VARIANT (type
);
1242 if (type1
== chill_integer_type_node
)
1243 return chill_unsigned_type_node
;
1245 return unsigned_type (type
);