summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-sink.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-sink.c')
-rw-r--r--gcc/tree-ssa-sink.c112
1 files changed, 54 insertions, 58 deletions
diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c
index ebf54e2070b..e56cce0edb1 100644
--- a/gcc/tree-ssa-sink.c
+++ b/gcc/tree-ssa-sink.c
@@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic.h"
#include "tree-inline.h"
#include "tree-flow.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "tree-dump.h"
#include "timevar.h"
#include "fibheap.h"
@@ -82,18 +82,18 @@ static struct
we return NULL. */
static basic_block
-find_bb_for_arg (tree phi, tree def)
+find_bb_for_arg (gimple phi, tree def)
{
- int i;
+ size_t i;
bool foundone = false;
basic_block result = NULL;
- for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ for (i = 0; i < gimple_phi_num_args (phi); i++)
if (PHI_ARG_DEF (phi, i) == def)
{
if (foundone)
return NULL;
foundone = true;
- result = PHI_ARG_EDGE (phi, i)->src;
+ result = gimple_phi_arg_edge (phi, i)->src;
}
return result;
}
@@ -107,9 +107,9 @@ find_bb_for_arg (tree phi, tree def)
used in, so that you only have one place you can sink it to. */
static bool
-all_immediate_uses_same_place (tree stmt)
+all_immediate_uses_same_place (gimple stmt)
{
- tree firstuse = NULL_TREE;
+ gimple firstuse = NULL;
ssa_op_iter op_iter;
imm_use_iterator imm_iter;
use_operand_p use_p;
@@ -119,7 +119,7 @@ all_immediate_uses_same_place (tree stmt)
{
FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var)
{
- if (firstuse == NULL_TREE)
+ if (firstuse == NULL)
firstuse = USE_STMT (use_p);
else
if (firstuse != USE_STMT (use_p))
@@ -134,16 +134,16 @@ all_immediate_uses_same_place (tree stmt)
but we still must avoid moving them around. */
bool
-is_hidden_global_store (tree stmt)
+is_hidden_global_store (gimple stmt)
{
/* Check virtual definitions. If we get here, the only virtual
- definitions we should see are those generated by assignment
+ definitions we should see are those generated by assignment or call
statements. */
if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
{
tree lhs;
- gcc_assert (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT);
+ gcc_assert (is_gimple_assign (stmt) || is_gimple_call (stmt));
/* Note that we must not check the individual virtual operands
here. In particular, if this is an aliased store, we could
@@ -170,7 +170,8 @@ is_hidden_global_store (tree stmt)
address is a pointer, we check if its name tag or symbol tag is
a global variable. Otherwise, we check if the base variable
is a global. */
- lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+ lhs = gimple_get_lhs (stmt);
+
if (REFERENCE_CLASS_P (lhs))
lhs = get_base_address (lhs);
@@ -200,7 +201,7 @@ is_hidden_global_store (tree stmt)
/* Find the nearest common dominator of all of the immediate uses in IMM. */
static basic_block
-nearest_common_dominator_of_uses (tree stmt)
+nearest_common_dominator_of_uses (gimple stmt)
{
bitmap blocks = BITMAP_ALLOC (NULL);
basic_block commondom;
@@ -216,18 +217,18 @@ nearest_common_dominator_of_uses (tree stmt)
{
FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var)
{
- tree usestmt = USE_STMT (use_p);
+ gimple usestmt = USE_STMT (use_p);
basic_block useblock;
- if (TREE_CODE (usestmt) == PHI_NODE)
+ if (gimple_code (usestmt) == GIMPLE_PHI)
{
int idx = PHI_ARG_INDEX_FROM_USE (use_p);
- useblock = PHI_ARG_EDGE (usestmt, idx)->src;
+ useblock = gimple_phi_arg_edge (usestmt, idx)->src;
}
else
{
- useblock = bb_for_stmt (usestmt);
+ useblock = gimple_bb (usestmt);
}
/* Short circuit. Nothing dominates the entry block. */
@@ -249,23 +250,22 @@ nearest_common_dominator_of_uses (tree stmt)
/* Given a statement (STMT) and the basic block it is currently in (FROMBB),
determine the location to sink the statement to, if any.
- Returns true if there is such location; in that case, TOBB is set to the
- basic block of the location, and TOBSI points to the statement before
- that STMT should be moved. */
+ Returns true if there is such location; in that case, TOGSI points to the
+ statement before that STMT should be moved. */
static bool
-statement_sink_location (tree stmt, basic_block frombb, basic_block *tobb,
- block_stmt_iterator *tobsi)
+statement_sink_location (gimple stmt, basic_block frombb,
+ gimple_stmt_iterator *togsi)
{
- tree use, def;
+ gimple use;
+ tree def;
use_operand_p one_use = NULL_USE_OPERAND_P;
basic_block sinkbb;
use_operand_p use_p;
def_operand_p def_p;
ssa_op_iter iter;
- stmt_ann_t ann;
- tree rhs;
imm_use_iterator imm_iter;
+ enum tree_code code;
FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
{
@@ -281,9 +281,8 @@ statement_sink_location (tree stmt, basic_block frombb, basic_block *tobb,
if (one_use == NULL_USE_OPERAND_P)
return false;
- if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
return false;
- rhs = GIMPLE_STMT_OPERAND (stmt, 1);
/* There are a few classes of things we can't or don't move, some because we
don't have code to handle it, some because it's not profitable and some
@@ -305,13 +304,13 @@ statement_sink_location (tree stmt, basic_block frombb, basic_block *tobb,
sunk.
*/
- ann = stmt_ann (stmt);
+ code = gimple_assign_rhs_code (stmt);
if (stmt_ends_bb_p (stmt)
- || TREE_SIDE_EFFECTS (rhs)
- || TREE_CODE (rhs) == EXC_PTR_EXPR
- || TREE_CODE (rhs) == FILTER_EXPR
+ || gimple_has_side_effects (stmt)
+ || code == EXC_PTR_EXPR
+ || code == FILTER_EXPR
|| is_hidden_global_store (stmt)
- || ann->has_volatile_ops
+ || gimple_has_volatile_ops (stmt)
|| !ZERO_SSA_OPERANDS (stmt, SSA_OP_VUSE))
return false;
@@ -365,20 +364,19 @@ statement_sink_location (tree stmt, basic_block frombb, basic_block *tobb,
fprintf (dump_file, "Common dominator of all uses is %d\n",
commondom->index);
}
- *tobb = commondom;
- *tobsi = bsi_after_labels (commondom);
+ *togsi = gsi_after_labels (commondom);
return true;
}
use = USE_STMT (one_use);
- if (TREE_CODE (use) != PHI_NODE)
+ if (gimple_code (use) != GIMPLE_PHI)
{
- sinkbb = bb_for_stmt (use);
+ sinkbb = gimple_bb (use);
if (sinkbb == frombb || sinkbb->loop_depth > frombb->loop_depth
|| sinkbb->loop_father != frombb->loop_father)
return false;
- *tobb = sinkbb;
- *tobsi = bsi_for_stmt (use);
+
+ *togsi = gsi_for_stmt (use);
return true;
}
@@ -399,14 +397,13 @@ statement_sink_location (tree stmt, basic_block frombb, basic_block *tobb,
If the use is a phi, and is in the same bb as the def,
we can't sink it. */
- if (bb_for_stmt (use) == frombb)
+ if (gimple_bb (use) == frombb)
return false;
if (sinkbb == frombb || sinkbb->loop_depth > frombb->loop_depth
|| sinkbb->loop_father != frombb->loop_father)
return false;
- *tobb = sinkbb;
- *tobsi = bsi_after_labels (sinkbb);
+ *togsi = gsi_after_labels (sinkbb);
return true;
}
@@ -417,7 +414,7 @@ static void
sink_code_in_bb (basic_block bb)
{
basic_block son;
- block_stmt_iterator bsi;
+ gimple_stmt_iterator gsi;
edge_iterator ei;
edge e;
bool last = true;
@@ -432,50 +429,49 @@ sink_code_in_bb (basic_block bb)
if (e->flags & EDGE_ABNORMAL)
goto earlyout;
- for (bsi = bsi_last (bb); !bsi_end_p (bsi);)
+ for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi);)
{
- tree stmt = bsi_stmt (bsi);
- block_stmt_iterator tobsi;
- basic_block tobb;
+ gimple stmt = gsi_stmt (gsi);
+ gimple_stmt_iterator togsi;
- if (!statement_sink_location (stmt, bb, &tobb, &tobsi))
+ if (!statement_sink_location (stmt, bb, &togsi))
{
- if (!bsi_end_p (bsi))
- bsi_prev (&bsi);
+ if (!gsi_end_p (gsi))
+ gsi_prev (&gsi);
last = false;
continue;
}
if (dump_file)
{
fprintf (dump_file, "Sinking ");
- print_generic_expr (dump_file, stmt, TDF_VOPS);
+ print_gimple_stmt (dump_file, stmt, 0, TDF_VOPS);
fprintf (dump_file, " from bb %d to bb %d\n",
- bb->index, tobb->index);
+ bb->index, (gsi_bb (togsi))->index);
}
/* If this is the end of the basic block, we need to insert at the end
of the basic block. */
- if (bsi_end_p (tobsi))
- bsi_move_to_bb_end (&bsi, tobb);
+ if (gsi_end_p (togsi))
+ gsi_move_to_bb_end (&gsi, gsi_bb (togsi));
else
- bsi_move_before (&bsi, &tobsi);
+ gsi_move_before (&gsi, &togsi);
sink_stats.sunk++;
/* If we've just removed the last statement of the BB, the
- bsi_end_p() test below would fail, but bsi_prev() would have
+ gsi_end_p() test below would fail, but gsi_prev() would have
succeeded, and we want it to succeed. So we keep track of
whether we're at the last statement and pick up the new last
statement. */
if (last)
{
- bsi = bsi_last (bb);
+ gsi = gsi_last_bb (bb);
continue;
}
last = false;
- if (!bsi_end_p (bsi))
- bsi_prev (&bsi);
+ if (!gsi_end_p (gsi))
+ gsi_prev (&gsi);
}
earlyout: