processed. This is a little slower than the FAST version since it adds a
placeholder element and must sort through the list a bit for each statement.
This placeholder element must be also be removed if the loop is
-terminated early. The macro @code{BREAK_FROM_IMM_USE_STMT} is provided
-to do this :
-
-@smallexample
- FOR_EACH_IMM_USE_STMT (stmt, iterator, ssa_var)
- @{
- if (stmt == last_stmt)
- BREAK_FROM_IMM_USE_STMT (iterator);
-
- FOR_EACH_IMM_USE_ON_STMT (imm_use_p, iterator)
- SET_USE (imm_use_p, ssa_var_2);
- fold_stmt (stmt);
- @}
-@end smallexample
+terminated early; a destructor takes care of that when leaving the
+@code{FOR_EACH_IMM_USE_STMT} scope.
There are checks in @code{verify_ssa} which verify that the immediate use list
is up to date, as well as checking that an optimization didn't break from the
recurse + 1))
{
retval = false;
- BREAK_FROM_IMM_USE_STMT (iter);
+ break;
}
}
&& (def_bb != gimple_bb (use_stmt) && !is_gimple_debug (use_stmt)))
{
add_write (writes, def);
- /* This is required by the FOR_EACH_IMM_USE_STMT when we want to break
- before all the uses have been visited. */
- BREAK_FROM_IMM_USE_STMT (imm_iter);
+ break;
}
}
FOR_EACH_IMM_USE_STMT (use_stmt, ui, name)
{
if (lattice[index].flags == 0)
- {
- BREAK_FROM_IMM_USE_STMT (ui);
- }
+ break;
if (is_gimple_debug (use_stmt))
continue;
if (dump_file)
{
tree op2 = gimple_cond_rhs (cond);
if (!integer_zerop (op2))
- RETURN_FROM_IMM_USE_STMT (use_iter, false);
+ return false;
}
else if (gassign *ga = dyn_cast<gassign *> (use_stmt))
{
enum tree_code code = gimple_assign_rhs_code (ga);
if (TREE_CODE_CLASS (code) != tcc_comparison)
- RETURN_FROM_IMM_USE_STMT (use_iter, false);
+ return false;
if (!integer_zerop (gimple_assign_rhs2 (ga)))
- RETURN_FROM_IMM_USE_STMT (use_iter, false);
+ return false;
}
else if (is_gimple_debug (use_stmt))
;
else if (use_stmt != stmt)
- RETURN_FROM_IMM_USE_STMT (use_iter, false);
+ return false;
return true;
}
|| (arg_count = gimple_call_num_args (call)) == 0)
{
res = -1;
- BREAK_FROM_IMM_USE_STMT (imm_iter);
+ break;
}
cgraph_edge *cs = node->get_edge (stmt);
|| all_uses != simple_uses)
{
res = -1;
- BREAK_FROM_IMM_USE_STMT (imm_iter);
+ break;
}
res += all_uses;
}
if (TREE_CODE (lhs) != SSA_NAME)
{
res = -1;
- BREAK_FROM_IMM_USE_STMT (imm_iter);
+ break;
}
gcc_assert (!gimple_vdef (stmt));
if (bitmap_set_bit (analyzed, SSA_NAME_VERSION (lhs)))
if (tmp < 0)
{
res = tmp;
- BREAK_FROM_IMM_USE_STMT (imm_iter);
+ break;
}
res += tmp;
}
else
{
res = -1;
- BREAK_FROM_IMM_USE_STMT (imm_iter);
+ break;
}
}
return res;
|| (arg_count = gimple_call_num_args (call)) == 0)
{
ret = true;
- BREAK_FROM_IMM_USE_STMT (ui);
+ break;
}
cgraph_edge *cs = node->get_edge (stmt);
if (uses_ok != all_uses)
{
ret = true;
- BREAK_FROM_IMM_USE_STMT (ui);
+ break;
}
}
if (t != name)
{
res = false;
- BREAK_FROM_IMM_USE_STMT (imm_iter);
+ break;
}
}
else if ((is_gimple_assign (stmt) && !gimple_has_volatile_ops (stmt))
if (TREE_CODE (lhs) != SSA_NAME)
{
res = false;
- BREAK_FROM_IMM_USE_STMT (imm_iter);
+ break;
}
gcc_assert (!gimple_vdef (stmt));
if (bitmap_set_bit (analyzed, SSA_NAME_VERSION (lhs))
&& !ssa_name_only_returned_p (lhs, analyzed))
{
res = false;
- BREAK_FROM_IMM_USE_STMT (imm_iter);
+ break;
}
}
else
{
res = false;
- BREAK_FROM_IMM_USE_STMT (imm_iter);
+ break;
}
}
return res;
!end_readonly_imm_use_p (&(ITER)); \
(void) ((DEST) = next_readonly_imm_use (&(ITER))))
-/* Use this iterator to visit each stmt which has a use of SSAVAR. */
+/* Forward declare for use in the class below. */
+static inline void end_imm_use_stmt_traverse (imm_use_iterator *);
+
+/* arrange to automatically call, upon descruction, end_imm_use_stmt_traverse
+ with a given pointer to imm_use_iterator. */
+struct auto_end_imm_use_stmt_traverse
+{
+ imm_use_iterator *imm;
+ auto_end_imm_use_stmt_traverse (imm_use_iterator *imm)
+ : imm (imm) {}
+ ~auto_end_imm_use_stmt_traverse ()
+ { end_imm_use_stmt_traverse (imm); }
+};
+
+/* Use this iterator to visit each stmt which has a use of SSAVAR. The
+ destructor of the auto_end_imm_use_stmt_traverse object deals with removing
+ ITER from SSAVAR's IMM_USE list even when leaving the scope early. */
#define FOR_EACH_IMM_USE_STMT(STMT, ITER, SSAVAR) \
- for ((STMT) = first_imm_use_stmt (&(ITER), (SSAVAR)); \
+ for (struct auto_end_imm_use_stmt_traverse \
+ auto_end_imm_use_stmt_traverse \
+ ((((STMT) = first_imm_use_stmt (&(ITER), (SSAVAR))), \
+ &(ITER))); \
!end_imm_use_stmt_p (&(ITER)); \
(void) ((STMT) = next_imm_use_stmt (&(ITER))))
-/* Use this to terminate the FOR_EACH_IMM_USE_STMT loop early. Failure to
- do so will result in leaving a iterator marker node in the immediate
- use list, and nothing good will come from that. */
-#define BREAK_FROM_IMM_USE_STMT(ITER) \
- { \
- end_imm_use_stmt_traverse (&(ITER)); \
- break; \
- }
-
-/* Similarly for return. */
-#define RETURN_FROM_IMM_USE_STMT(ITER, VAL) \
- { \
- end_imm_use_stmt_traverse (&(ITER)); \
- return (VAL); \
- }
-
/* Use this iterator in combination with FOR_EACH_IMM_USE_STMT to
get access to each occurrence of ssavar on the stmt returned by
that iterator.. for instance:
&& flow_bb_inside_loop_p (loop, gimple_bb (stmt)))
{
phi = stmt;
- BREAK_FROM_IMM_USE_STMT (iter);
+ break;
}
}
if (!phi)
}
use_bool = false;
- BREAK_FROM_IMM_USE_STMT (iter);
+ break;
}
tree new_lhs = make_ssa_name (TREE_TYPE (lhs));
|| gimple_plf (stmt, STMT_NECESSARY))
{
found = true;
- BREAK_FROM_IMM_USE_STMT (iter);
+ break;
}
}
if (found)
{
/* Limit stmt walking. */
if (++cnt > param_dse_max_alias_queries_per_store)
- BREAK_FROM_IMM_USE_STMT (ui);
+ break;
/* If USE_STMT stores 0 into one or more of the same locations
as STMT and STMT would kill USE_STMT, then we can just remove
ao_ref write;
if (!initialize_ao_ref_for_dse (use_stmt, &write))
- BREAK_FROM_IMM_USE_STMT (ui)
+ break;
if (valid_ao_ref_for_dse (&write)
&& stmt_kills_ref_p (stmt, &write))
if (++cnt > param_dse_max_alias_queries_per_store)
{
fail = true;
- BREAK_FROM_IMM_USE_STMT (ui);
+ break;
}
/* We have visited ourselves already so ignore STMT for the
}
fail = true;
- BREAK_FROM_IMM_USE_STMT (ui);
+ break;
}
/* If this is a store, remember it as we possibly need to walk the
defs uses. */
count++;
if (count > 1)
- BREAK_FROM_IMM_USE_STMT (imm_iter);
+ break;
}
if (!count)
and, in subsequent rounds, that the built_in type is the same
type, or a compatible type. */
if (type != t && !types_compatible_p (type, t))
- RETURN_FROM_IMM_USE_STMT (use_iter, false);
+ return false;
}
if (seen_cos + seen_sin + seen_cexpi <= 1)
return false;
&& !dominated_by_p (CDI_DOMINATORS, gimple_bb (use_stmt), bb))
{
ok = false;
- BREAK_FROM_IMM_USE_STMT (ui2);
+ break;
}
}
}
if (!remove_now)
- BREAK_FROM_IMM_USE_STMT (uit);
+ break;
}
if (remove_now)
mark_visited = false;
else
STMT_VINFO_LIVE_P (stmt_info) = false;
- BREAK_FROM_IMM_USE_STMT (use_iter);
+ break;
}
}
/* We have to verify whether we can insert the lane extract
(vect_stmt_to_vectorize (use_stmt_info)))
{
(*life)[i] = true;
- BREAK_FROM_IMM_USE_STMT (use_iter);
+ break;
}
}
}