/* High-level loop manipulation functions.
Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-
+
This file is part of GCC.
-
+
GCC is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
later version.
-
+
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
-
+
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
It is expected that neither BASE nor STEP are shared with other expressions
(unless the sharing rules allow this). Use VAR as a base var_decl for it
(if NULL, a new temporary will be created). The increment will occur at
- INCR_POS (after it if AFTER is true, before it otherwise). INCR_POS and
+ INCR_POS (after it if AFTER is true, before it otherwise). INCR_POS and
AFTER can be computed using standard_iv_increment_position. The ssa versions
of the variable before and after increment will be stored in VAR_BEFORE and
VAR_AFTER (unless they are NULL). */
stmt = create_phi_node (vb, loop->header);
SSA_NAME_DEF_STMT (vb) = stmt;
- add_phi_arg (stmt, initial, loop_preheader_edge (loop));
- add_phi_arg (stmt, va, loop_latch_edge (loop));
+ add_phi_arg (stmt, initial, loop_preheader_edge (loop), UNKNOWN_LOCATION);
+ add_phi_arg (stmt, va, loop_latch_edge (loop), UNKNOWN_LOCATION);
}
/* Add exit phis for the USE on EXIT. */
create_new_def_for (gimple_phi_result (phi), phi,
gimple_phi_result_ptr (phi));
FOR_EACH_EDGE (e, ei, exit->preds)
- add_phi_arg (phi, use, e);
+ add_phi_arg (phi, use, e, UNKNOWN_LOCATION);
}
/* Add exit phis for VAR that is used in LIVEIN.
tree var;
basic_block bb = gimple_bb (stmt);
+ if (is_gimple_debug (stmt))
+ return;
+
FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_ALL_USES)
find_uses_to_rename_use (bb, var, use_blocks, need_phis);
}
for (bsi = gsi_start_phis (e->dest); !gsi_end_p (bsi); gsi_next (&bsi))
find_uses_to_rename_use (bb, PHI_ARG_DEF_FROM_EDGE (gsi_stmt (bsi), e),
use_blocks, need_phis);
-
+
for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
find_uses_to_rename_stmt (gsi_stmt (bsi), use_blocks, need_phis);
}
-
+
/* Marks names that are used outside of the loop they are defined in
for rewrite. Records the set of blocks in that the ssa
names are defined to USE_BLOCKS. If CHANGED_BBS is not NULL,
Looking from the outer loop with the normal SSA form, the first use of k
is not well-behaved, while the second one is an induction variable with
base 99 and step 1.
-
+
If CHANGED_BBS is not NULL, we look for uses outside loops only in
the basic blocks in this set.
{
gimple def;
basic_block def_bb;
-
+
if (TREE_CODE (use) != SSA_NAME || !is_gimple_reg (use))
return;
ssa_op_iter iter;
tree var;
+ if (is_gimple_debug (stmt))
+ return;
+
FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_ALL_USES)
check_loop_closed_ssa_use (bb, var);
}
tree new_name, name;
use_operand_p op_p;
gimple_stmt_iterator psi;
+ source_location locus;
for (psi = gsi_start_phis (dest); !gsi_end_p (psi); gsi_next (&psi))
{
phi = gsi_stmt (psi);
op_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (bb));
+ locus = gimple_phi_arg_location_from_edge (phi, single_succ_edge (bb));
name = USE_FROM_PTR (op_p);
new_name = duplicate_ssa_name (name, NULL);
new_phi = create_phi_node (new_name, bb);
SSA_NAME_DEF_STMT (new_name) = new_phi;
- add_phi_arg (new_phi, name, exit);
+ add_phi_arg (new_phi, name, exit, locus);
SET_USE (op_p, new_name);
}
If N is number of iterations of the loop and MAY_BE_ZERO is the condition
under that loop exits in the first iteration even if N != 0,
-
+
while (1)
{
x = phi (init, next);
becomes (with possibly the exit conditions formulated a bit differently,
avoiding the need to create a new iv):
-
+
if (MAY_BE_ZERO || N < FACTOR)
goto rest;
pre;
post;
N -= FACTOR;
-
+
} while (N >= FACTOR);
rest:
break;
post;
}
-
+
Before the loop is unrolled, TRANSFORM is called for it (only for the
unrolled loop, but not for its versioned copy). DATA is passed to
TRANSFORM. */
phi_rest = create_phi_node (new_init, rest);
SSA_NAME_DEF_STMT (new_init) = phi_rest;
- add_phi_arg (phi_rest, init, precond_edge);
- add_phi_arg (phi_rest, next, new_exit);
+ add_phi_arg (phi_rest, init, precond_edge, UNKNOWN_LOCATION);
+ add_phi_arg (phi_rest, next, new_exit, UNKNOWN_LOCATION);
SET_USE (op, new_init);
}