/* Build expressions with type checking for C compiler.
- Copyright (C) 1987, 1988, 1989, 1992 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1988, 1989, 1992, 1993 Free Software Foundation, Inc.
This file is part of GNU CC.
#include "rtl.h"
static void expand_stmt_with_iterators_1 ();
-static tree collect_iterators();
+static tree collect_iterators ();
static void iterator_loop_prologue ();
static void iterator_loop_epilogue ();
static void add_ixpansion ();
struct iter_stack_node *iter_stack;
struct iter_stack_node sublevel_ixpansions;
+
+/* During collect_iterators, a list of SAVE_EXPRs already scanned. */
+static tree save_exprs;
\f
/* Initialize our obstack once per compilation. */
iterator_expand (stmt)
tree stmt;
{
- tree iter_list = collect_iterators (stmt, NULL_TREE);
+ tree iter_list;
+ save_exprs = NULL_TREE;
+ iter_list = collect_iterators (stmt, NULL_TREE);
expand_stmt_with_iterators_1 (stmt, iter_list);
istack_sublevel_to_current ();
}
return list;
}
+ case SAVE_EXPR:
+ /* In each scan, scan a given save_expr only once. */
+ if (value_member (exp, save_exprs))
+ return list;
+
+ save_exprs = tree_cons (NULL_TREE, exp, save_exprs);
+ return collect_iterators (TREE_OPERAND (exp, 0), list);
+
/* we do not automatically iterate blocks -- one must */
/* use the FOR construct to do that */
/* Some tree codes have RTL, not trees, as operands. */
switch (TREE_CODE (exp))
{
- case SAVE_EXPR:
case CALL_EXPR:
num_args = 2;
break;
tree idecl;
rtx *start_note, *end_note;
{
+ tree expr;
+
/* Force the save_expr in DECL_INITIAL to be calculated
if it hasn't been calculated yet. */
- expand_expr (DECL_INITIAL (idecl), 0, VOIDmode, 0);
+ expand_expr (DECL_INITIAL (idecl), const0_rtx, VOIDmode, 0);
if (DECL_RTL (idecl) == 0)
expand_decl (idecl);
if (start_note)
*start_note = emit_note (0, NOTE_INSN_DELETED);
+
/* Initialize counter. */
- expand_expr (build (MODIFY_EXPR, TREE_TYPE (idecl),
- idecl, integer_zero_node),
- 0, VOIDmode, 0);
+ expr = build (MODIFY_EXPR, TREE_TYPE (idecl), idecl, integer_zero_node);
+ TREE_SIDE_EFFECTS (expr) = 1;
+ expand_expr (expr, const0_rtx, VOIDmode, 0);
expand_start_loop_continue_elsewhere (1);
*start_note = emit_note (0, NOTE_INSN_DELETED);
expand_loop_continue_here ();
incr = build_binary_op (PLUS_EXPR, idecl, integer_one_node, 0);
- expand_expr (build (MODIFY_EXPR, TREE_TYPE (idecl), idecl, incr),
- 0, VOIDmode, 0);
+ incr = build (MODIFY_EXPR, TREE_TYPE (idecl), idecl, incr);
+ TREE_SIDE_EFFECTS (incr) = 1;
+ expand_expr (incr, const0_rtx, VOIDmode, 0);
test = build_binary_op (LT_EXPR, idecl, DECL_INITIAL (idecl), 0);
expand_exit_loop_if_false (0, test);
expand_end_loop ();