/* Loop invariant motion.
- Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of GCC.
return MOVE_POSSIBLE;
}
- if (TREE_CODE (stmt) != MODIFY_EXPR)
+ if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
return MOVE_IMPOSSIBLE;
if (stmt_ends_bb_p (stmt))
if (stmt_ann (stmt)->has_volatile_ops)
return MOVE_IMPOSSIBLE;
- lhs = TREE_OPERAND (stmt, 0);
+ lhs = GIMPLE_STMT_OPERAND (stmt, 0);
if (TREE_CODE (lhs) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
return MOVE_IMPOSSIBLE;
- rhs = TREE_OPERAND (stmt, 1);
+ rhs = GIMPLE_STMT_OPERAND (stmt, 1);
if (TREE_SIDE_EFFECTS (rhs))
return MOVE_IMPOSSIBLE;
if (class != tcc_unary
&& class != tcc_binary
&& class != tcc_expression
+ && class != tcc_vl_exp
&& class != tcc_comparison)
return NULL;
- nops = TREE_CODE_LENGTH (TREE_CODE (expr));
+ nops = TREE_OPERAND_LENGTH (expr);
for (i = 0; i < nops; i++)
{
aloop = outermost_invariant_loop_expr (TREE_OPERAND (expr, i), loop);
if (TREE_CODE (stmt) == COND_EXPR)
return LIM_EXPENSIVE;
- rhs = TREE_OPERAND (stmt, 1);
+ rhs = GENERIC_TREE_OPERAND (stmt, 1);
/* Hoisting memory references out should almost surely be a win. */
if (stmt_references_memory_p (stmt))
if (!add_dependency (val, lim_data, loop, true))
return false;
- FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS)
+ FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_VIRTUAL_USES)
if (!add_dependency (val, lim_data, loop, false))
return false;
/* If divisor is invariant, convert a/b to a*(1/b), allowing reciprocal
to be hoisted out of loop, saving expensive divide. */
if (pos == MOVE_POSSIBLE
- && (rhs = TREE_OPERAND (stmt, 1)) != NULL
+ && (rhs = GENERIC_TREE_OPERAND (stmt, 1)) != NULL
&& TREE_CODE (rhs) == RDIV_EXPR
&& flag_unsafe_math_optimizations
&& !flag_trapping_math
&& outermost_invariant_loop_expr (rhs,
loop_containing_stmt (stmt)) == NULL)
{
- tree lhs, stmt1, stmt2, var, name;
+ tree lhs, stmt1, stmt2, var, name, tmp;
- lhs = TREE_OPERAND (stmt, 0);
+ lhs = GENERIC_TREE_OPERAND (stmt, 0);
- /* stmt must be MODIFY_EXPR. */
+ /* stmt must be GIMPLE_MODIFY_STMT. */
var = create_tmp_var (TREE_TYPE (rhs), "reciptmp");
add_referenced_var (var);
- stmt1 = build2 (MODIFY_EXPR, void_type_node, var,
- build2 (RDIV_EXPR, TREE_TYPE (rhs),
- build_real (TREE_TYPE (rhs), dconst1),
- TREE_OPERAND (rhs, 1)));
+ tmp = build2 (RDIV_EXPR, TREE_TYPE (rhs),
+ build_real (TREE_TYPE (rhs), dconst1),
+ TREE_OPERAND (rhs, 1));
+ stmt1 = build_gimple_modify_stmt (var, tmp);
name = make_ssa_name (var, stmt1);
- TREE_OPERAND (stmt1, 0) = name;
- stmt2 = build2 (MODIFY_EXPR, void_type_node, lhs,
- build2 (MULT_EXPR, TREE_TYPE (rhs),
- name, TREE_OPERAND (rhs, 0)));
+ GIMPLE_STMT_OPERAND (stmt1, 0) = name;
+ tmp = build2 (MULT_EXPR, TREE_TYPE (rhs),
+ name, TREE_OPERAND (rhs, 0));
+ stmt2 = build_gimple_modify_stmt (lhs, tmp);
/* Replace division stmt with reciprocal and multiply stmts.
The multiply stmt is not invariant, so update iterator
if (class != tcc_unary
&& class != tcc_binary
&& class != tcc_expression
+ && class != tcc_vl_exp
&& class != tcc_comparison)
return;
- nops = TREE_CODE_LENGTH (TREE_CODE (expr));
+ nops = TREE_OPERAND_LENGTH (expr);
for (i = 0; i < nops; i++)
force_move_till_expr (TREE_OPERAND (expr, i), orig_loop, loop);
}
LIM_DATA (aref->stmt)->sm_done = true;
/* Emit the load & stores. */
- load = build2 (MODIFY_EXPR, void_type_node, tmp_var, ref);
+ load = build_gimple_modify_stmt (tmp_var, ref);
get_stmt_ann (load)->common.aux = xcalloc (1, sizeof (struct lim_aux_data));
LIM_DATA (load)->max_loop = loop;
LIM_DATA (load)->tgt_loop = loop;
for (i = 0; VEC_iterate (edge, exits, i, ex); i++)
{
- store = build2 (MODIFY_EXPR, void_type_node,
- unshare_expr (ref), tmp_var);
+ store = build_gimple_modify_stmt (unshare_expr (ref), tmp_var);
bsi_insert_on_edge (ex, store);
}
}
return;
/* Recognize MEM = (SSA_NAME | invariant) and SSA_NAME = MEM patterns. */
- if (TREE_CODE (stmt) != MODIFY_EXPR)
+ if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
goto fail;
- lhs = &TREE_OPERAND (stmt, 0);
- rhs = &TREE_OPERAND (stmt, 1);
+ lhs = &GIMPLE_STMT_OPERAND (stmt, 0);
+ rhs = &GIMPLE_STMT_OPERAND (stmt, 1);
if (TREE_CODE (*lhs) == SSA_NAME)
{
}
ref->is_stored |= is_stored;
- FOR_EACH_SSA_TREE_OPERAND (vname, stmt, oi,
- SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS)
+ FOR_EACH_SSA_TREE_OPERAND (vname, stmt, oi, SSA_OP_VIRTUAL_USES)
bitmap_set_bit (ref->vops, DECL_UID (SSA_NAME_VAR (vname)));
record_mem_ref_loc (&ref->locs, stmt, mem);
return;
fail:
- FOR_EACH_SSA_TREE_OPERAND (vname, stmt, oi,
- SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS)
+ FOR_EACH_SSA_TREE_OPERAND (vname, stmt, oi, SSA_OP_VIRTUAL_USES)
bitmap_set_bit (clobbered_vops, DECL_UID (SSA_NAME_VAR (vname)));
}
determine_lsm (void)
{
struct loop *loop;
-
- if (!current_loops->tree_root->inner)
- return;
+ loop_iterator li;
/* Pass the loops from the outermost and perform the store motion as
suitable. */
- loop = current_loops->tree_root->inner;
- while (1)
+ FOR_EACH_LOOP (li, loop, 0)
{
determine_lsm_loop (loop);
-
- if (loop->inner)
- {
- loop = loop->inner;
- continue;
- }
- while (!loop->next)
- {
- loop = loop->outer;
- if (loop == current_loops->tree_root)
- {
- bsi_commit_edge_inserts ();
- return;
- }
- }
- loop = loop->next;
}
+
+ bsi_commit_edge_inserts ();
}
/* Fills ALWAYS_EXECUTED_IN information for basic blocks of LOOP, i.e.