Index: gcc/gcc/tree-ssa-sink.c |
diff --git a/gcc/gcc/tree-ssa-sink.c b/gcc/gcc/tree-ssa-sink.c |
index a190a22f5cc7fb8f5ac439772e3a54c2b855f8ea..bc6a7146b521ffb9c321743359030a6e400a8e42 100644 |
--- a/gcc/gcc/tree-ssa-sink.c |
+++ b/gcc/gcc/tree-ssa-sink.c |
@@ -53,7 +53,7 @@ along with GCC; see the file COPYING3. If not see |
else |
y = *q; |
- |
+ |
should become |
sinktemp = p; |
p = p + 1; |
@@ -65,16 +65,16 @@ along with GCC; see the file COPYING3. If not see |
y = *q |
} |
Store copy propagation will take care of the store elimination above. |
- |
+ |
2. Sinking using Partial Dead Code Elimination. */ |
static struct |
-{ |
+{ |
/* The number of statements sunk down the flowgraph by code sinking. */ |
int sunk; |
- |
+ |
} sink_stats; |
@@ -120,6 +120,8 @@ all_immediate_uses_same_place (gimple stmt) |
{ |
FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var) |
{ |
+ if (is_gimple_debug (USE_STMT (use_p))) |
+ continue; |
if (firstuse == NULL) |
firstuse = USE_STMT (use_p); |
else |
@@ -140,7 +142,7 @@ 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 or call |
statements. */ |
- if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS)) |
+ if (gimple_vdef (stmt)) |
{ |
tree lhs; |
@@ -191,7 +193,7 @@ is_hidden_global_store (gimple stmt) |
} |
else if (INDIRECT_REF_P (lhs)) |
- return may_point_to_global_var (TREE_OPERAND (lhs, 0)); |
+ return ptr_deref_may_alias_global_p (TREE_OPERAND (lhs, 0)); |
else |
gcc_unreachable (); |
} |
@@ -202,8 +204,8 @@ is_hidden_global_store (gimple stmt) |
/* Find the nearest common dominator of all of the immediate uses in IMM. */ |
static basic_block |
-nearest_common_dominator_of_uses (gimple stmt) |
-{ |
+nearest_common_dominator_of_uses (gimple stmt, bool *debug_stmts) |
+{ |
bitmap blocks = BITMAP_ALLOC (NULL); |
basic_block commondom; |
unsigned int j; |
@@ -227,6 +229,11 @@ nearest_common_dominator_of_uses (gimple stmt) |
useblock = gimple_phi_arg_edge (usestmt, idx)->src; |
} |
+ else if (is_gimple_debug (usestmt)) |
+ { |
+ *debug_stmts = true; |
+ continue; |
+ } |
else |
{ |
useblock = gimple_bb (usestmt); |
@@ -243,13 +250,13 @@ nearest_common_dominator_of_uses (gimple stmt) |
} |
commondom = BASIC_BLOCK (bitmap_first_set_bit (blocks)); |
EXECUTE_IF_SET_IN_BITMAP (blocks, 0, j, bi) |
- commondom = nearest_common_dominator (CDI_DOMINATORS, commondom, |
+ commondom = nearest_common_dominator (CDI_DOMINATORS, commondom, |
BASIC_BLOCK (j)); |
BITMAP_FREE (blocks); |
return commondom; |
} |
-/* Given a statement (STMT) and the basic block it is currently in (FROMBB), |
+/* 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, TOGSI points to the |
statement before that STMT should be moved. */ |
@@ -266,12 +273,14 @@ statement_sink_location (gimple stmt, basic_block frombb, |
def_operand_p def_p; |
ssa_op_iter iter; |
imm_use_iterator imm_iter; |
- enum tree_code code; |
FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS) |
{ |
FOR_EACH_IMM_USE_FAST (one_use, imm_iter, def) |
{ |
+ if (is_gimple_debug (USE_STMT (one_use))) |
+ continue; |
+ |
break; |
} |
if (one_use != NULL_USE_OPERAND_P) |
@@ -287,19 +296,19 @@ statement_sink_location (gimple stmt, basic_block frombb, |
/* 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 |
- because it's not legal. |
- |
+ because it's not legal. |
+ |
We can't sink things that may be global stores, at least not without |
calculating a lot more information, because we may cause it to no longer |
be seen by an external routine that needs it depending on where it gets |
- moved to. |
- |
+ moved to. |
+ |
We don't want to sink loads from memory. |
We can't sink statements that end basic blocks without splitting the |
incoming edge for the sink location to place it there. |
- We can't sink statements that have volatile operands. |
+ We can't sink statements that have volatile operands. |
We don't want to sink dead code, so anything with 0 immediate uses is not |
sunk. |
@@ -310,18 +319,15 @@ statement_sink_location (gimple stmt, basic_block frombb, |
to use specific hard registers. |
*/ |
- code = gimple_assign_rhs_code (stmt); |
if (stmt_ends_bb_p (stmt) |
|| gimple_has_side_effects (stmt) |
- || code == EXC_PTR_EXPR |
- || code == FILTER_EXPR |
|| is_hidden_global_store (stmt) |
|| gimple_has_volatile_ops (stmt) |
- || !ZERO_SSA_OPERANDS (stmt, SSA_OP_VUSE) |
+ || gimple_vuse (stmt) |
|| (cfun->has_local_explicit_reg_vars |
&& TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt))) == BLKmode)) |
return false; |
- |
+ |
FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_ALL_DEFS) |
{ |
tree def = DEF_FROM_PTR (def_p); |
@@ -329,31 +335,33 @@ statement_sink_location (gimple stmt, basic_block frombb, |
|| SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def)) |
return false; |
} |
- |
+ |
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES) |
{ |
tree use = USE_FROM_PTR (use_p); |
if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (use)) |
return false; |
} |
- |
+ |
/* If all the immediate uses are not in the same place, find the nearest |
common dominator of all the immediate uses. For PHI nodes, we have to |
find the nearest common dominator of all of the predecessor blocks, since |
that is where insertion would have to take place. */ |
if (!all_immediate_uses_same_place (stmt)) |
{ |
- basic_block commondom = nearest_common_dominator_of_uses (stmt); |
- |
+ bool debug_stmts = false; |
+ basic_block commondom = nearest_common_dominator_of_uses (stmt, |
+ &debug_stmts); |
+ |
if (commondom == frombb) |
return false; |
/* Our common dominator has to be dominated by frombb in order to be a |
trivially safe place to put this statement, since it has multiple |
- uses. */ |
+ uses. */ |
if (!dominated_by_p (CDI_DOMINATORS, commondom, frombb)) |
return false; |
- |
+ |
/* It doesn't make sense to move to a dominator that post-dominates |
frombb, because it means we've just moved it into a path that always |
executes if frombb executes, instead of reducing the number of |
@@ -372,7 +380,9 @@ statement_sink_location (gimple stmt, basic_block frombb, |
fprintf (dump_file, "Common dominator of all uses is %d\n", |
commondom->index); |
} |
+ |
*togsi = gsi_after_labels (commondom); |
+ |
return true; |
} |
@@ -384,7 +394,13 @@ statement_sink_location (gimple stmt, basic_block frombb, |
|| sinkbb->loop_father != frombb->loop_father) |
return false; |
+ /* Move the expression to a post dominator can't reduce the number of |
+ executions. */ |
+ if (dominated_by_p (CDI_POST_DOMINATORS, frombb, sinkbb)) |
+ return false; |
+ |
*togsi = gsi_for_stmt (use); |
+ |
return true; |
} |
@@ -399,10 +415,10 @@ statement_sink_location (gimple stmt, basic_block frombb, |
/* This will happen when you have |
a_3 = PHI <a_13, a_26> |
- |
- a_26 = VDEF <a_3> |
- If the use is a phi, and is in the same bb as the def, |
+ a_26 = VDEF <a_3> |
+ |
+ If the use is a phi, and is in the same bb as the def, |
we can't sink it. */ |
if (gimple_bb (use) == frombb) |
@@ -411,6 +427,11 @@ statement_sink_location (gimple stmt, basic_block frombb, |
|| sinkbb->loop_father != frombb->loop_father) |
return false; |
+ /* Move the expression to a post dominator can't reduce the number of |
+ executions. */ |
+ if (dominated_by_p (CDI_POST_DOMINATORS, frombb, sinkbb)) |
+ return false; |
+ |
*togsi = gsi_after_labels (sinkbb); |
return true; |
@@ -426,7 +447,7 @@ sink_code_in_bb (basic_block bb) |
edge_iterator ei; |
edge e; |
bool last = true; |
- |
+ |
/* If this block doesn't dominate anything, there can't be any place to sink |
the statements to. */ |
if (first_dom_son (CDI_DOMINATORS, bb) == NULL) |
@@ -439,7 +460,7 @@ sink_code_in_bb (basic_block bb) |
for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi);) |
{ |
- gimple stmt = gsi_stmt (gsi); |
+ gimple stmt = gsi_stmt (gsi); |
gimple_stmt_iterator togsi; |
if (!statement_sink_location (stmt, bb, &togsi)) |
@@ -448,7 +469,7 @@ sink_code_in_bb (basic_block bb) |
gsi_prev (&gsi); |
last = false; |
continue; |
- } |
+ } |
if (dump_file) |
{ |
fprintf (dump_file, "Sinking "); |
@@ -456,7 +477,7 @@ sink_code_in_bb (basic_block bb) |
fprintf (dump_file, " from bb %d to bb %d\n", |
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 (gsi_end_p (togsi)) |
@@ -480,7 +501,7 @@ sink_code_in_bb (basic_block bb) |
last = false; |
if (!gsi_end_p (gsi)) |
gsi_prev (&gsi); |
- |
+ |
} |
earlyout: |
for (son = first_dom_son (CDI_POST_DOMINATORS, bb); |
@@ -489,7 +510,7 @@ sink_code_in_bb (basic_block bb) |
{ |
sink_code_in_bb (son); |
} |
-} |
+} |
/* Perform code sinking. |
This moves code down the flowgraph when we know it would be |
@@ -497,7 +518,7 @@ sink_code_in_bb (basic_block bb) |
executions of the statement. |
IE given |
- |
+ |
a_1 = b + c; |
if (<something>) |
{ |
@@ -536,7 +557,7 @@ execute_sink_code (void) |
memset (&sink_stats, 0, sizeof (sink_stats)); |
calculate_dominance_info (CDI_DOMINATORS); |
calculate_dominance_info (CDI_POST_DOMINATORS); |
- sink_code_in_bb (EXIT_BLOCK_PTR); |
+ sink_code_in_bb (EXIT_BLOCK_PTR); |
statistics_counter_event (cfun, "Sunk statements", sink_stats.sunk); |
free_dominance_info (CDI_POST_DOMINATORS); |
remove_fake_exit_edges (); |
@@ -570,11 +591,11 @@ struct gimple_opt_pass pass_sink_code = |
0, /* static_pass_number */ |
TV_TREE_SINK, /* tv_id */ |
PROP_no_crit_edges | PROP_cfg |
- | PROP_ssa | PROP_alias, /* properties_required */ |
+ | PROP_ssa, /* properties_required */ |
0, /* properties_provided */ |
0, /* properties_destroyed */ |
0, /* todo_flags_start */ |
- TODO_update_ssa |
+ TODO_update_ssa |
| TODO_dump_func |
| TODO_ggc_collect |
| TODO_verify_ssa /* todo_flags_finish */ |