| 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 */
|
|
|