Commit cb8f1a57 by Bin Cheng Committed by Bin Cheng

re PR tree-optimization/60363 (logical_op_short_circuit,…

re PR tree-optimization/60363 (logical_op_short_circuit, gcc.dg/tree-ssa/ssa-dom-thread-4.c scan-tree-dump-times dom1 "Threaded" 4)


	PR tree-optimization/60363
	* gcc/tree-ssa-threadupdate.c (get_value_locus_in_path): New.
	(copy_phi_args): New parameters.  Call get_value_locus_in_path.
	(update_destination_phis): New parameter.
	(create_edge_and_update_destination_phis): Ditto.
	(ssa_fix_duplicate_block_edges): Pass new arguments.
	(thread_single_edge): Ditto.

	PR tree-optimization/60363
	* gcc.dg/tree-ssa/ssa-dom-thread-4.c: Revert XFAIL test.

From-SVN: r210059
parent f93bc5b3
2014-05-05 Bin Cheng <bin.cheng@arm.com>
PR tree-optimization/60363
* gcc/tree-ssa-threadupdate.c (get_value_locus_in_path): New.
(copy_phi_args): New parameters. Call get_value_locus_in_path.
(update_destination_phis): New parameter.
(create_edge_and_update_destination_phis): Ditto.
(ssa_fix_duplicate_block_edges): Pass new arguments.
(thread_single_edge): Ditto.
2014-05-04 Peter Bergner <bergner@vnet.ibm.com> 2014-05-04 Peter Bergner <bergner@vnet.ibm.com>
* config/rs6000/rs6000.h (RS6000_BTM_HARD_FLOAT): New define. * config/rs6000/rs6000.h (RS6000_BTM_HARD_FLOAT): New define.
......
2014-05-05 Bin Cheng <bin.cheng@arm.com>
PR tree-optimization/60363
* gcc.dg/tree-ssa/ssa-dom-thread-4.c: Revert XFAIL test.
2014-05-04 Peter Bergner <bergner@vnet.ibm.com> 2014-05-04 Peter Bergner <bergner@vnet.ibm.com>
* gcc.target/powerpc/pack02.c (dg-options): Add -mhard-float. * gcc.target/powerpc/pack02.c (dg-options): Add -mhard-float.
......
...@@ -75,6 +75,6 @@ bitmap_ior_and_compl (bitmap dst, const_bitmap a, const_bitmap b, ...@@ -75,6 +75,6 @@ bitmap_ior_and_compl (bitmap dst, const_bitmap a, const_bitmap b,
-> "kill_elt->indx == b_elt->indx" in the second condition, -> "kill_elt->indx == b_elt->indx" in the second condition,
skipping the known-true "b_elt && kill_elt" in the second skipping the known-true "b_elt && kill_elt" in the second
condition. */ condition. */
/* { dg-final { scan-tree-dump-times "Threaded" 4 "dom1" { target logical_op_short_circuit xfail logical_op_short_circuit } } } */ /* { dg-final { scan-tree-dump-times "Threaded" 4 "dom1" { target logical_op_short_circuit } } } */
/* { dg-final { cleanup-tree-dump "dom1" } } */ /* { dg-final { cleanup-tree-dump "dom1" } } */
...@@ -403,10 +403,59 @@ copy_phi_arg_into_existing_phi (edge src_e, edge tgt_e) ...@@ -403,10 +403,59 @@ copy_phi_arg_into_existing_phi (edge src_e, edge tgt_e)
} }
} }
/* For each PHI in BB, copy the argument associated with SRC_E to TGT_E. */ /* Given ssa_name DEF, backtrack jump threading PATH from node IDX
to see if it has constant value in a flow sensitive manner. Set
LOCUS to location of the constant phi arg and return the value.
Return DEF directly if either PATH or idx is ZERO. */
static tree
get_value_locus_in_path (tree def, vec<jump_thread_edge *> *path,
basic_block bb, int idx, source_location *locus)
{
tree arg;
gimple def_phi;
basic_block def_bb;
if (path == NULL || idx == 0)
return def;
def_phi = SSA_NAME_DEF_STMT (def);
if (gimple_code (def_phi) != GIMPLE_PHI)
return def;
def_bb = gimple_bb (def_phi);
/* Don't propagate loop invariants into deeper loops. */
if (!def_bb || bb_loop_depth (def_bb) < bb_loop_depth (bb))
return def;
/* Backtrack jump threading path from IDX to see if def has constant
value. */
for (int j = idx - 1; j >= 0; j--)
{
edge e = (*path)[j]->e;
if (e->dest == def_bb)
{
arg = gimple_phi_arg_def (def_phi, e->dest_idx);
if (is_gimple_min_invariant (arg))
{
*locus = gimple_phi_arg_location (def_phi, e->dest_idx);
return arg;
}
break;
}
}
return def;
}
/* For each PHI in BB, copy the argument associated with SRC_E to TGT_E.
Try to backtrack jump threading PATH from node IDX to see if the arg
has constant value, copy constant value instead of argument itself
if yes. */
static void static void
copy_phi_args (basic_block bb, edge src_e, edge tgt_e) copy_phi_args (basic_block bb, edge src_e, edge tgt_e,
vec<jump_thread_edge *> *path, int idx)
{ {
gimple_stmt_iterator gsi; gimple_stmt_iterator gsi;
int src_indx = src_e->dest_idx; int src_indx = src_e->dest_idx;
...@@ -414,8 +463,14 @@ copy_phi_args (basic_block bb, edge src_e, edge tgt_e) ...@@ -414,8 +463,14 @@ copy_phi_args (basic_block bb, edge src_e, edge tgt_e)
for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{ {
gimple phi = gsi_stmt (gsi); gimple phi = gsi_stmt (gsi);
tree def = gimple_phi_arg_def (phi, src_indx);
source_location locus = gimple_phi_arg_location (phi, src_indx); source_location locus = gimple_phi_arg_location (phi, src_indx);
add_phi_arg (phi, gimple_phi_arg_def (phi, src_indx), tgt_e, locus);
if (TREE_CODE (def) == SSA_NAME
&& !virtual_operand_p (gimple_phi_result (phi)))
def = get_value_locus_in_path (def, path, bb, idx, &locus);
add_phi_arg (phi, def, tgt_e, locus);
} }
} }
...@@ -423,10 +478,13 @@ copy_phi_args (basic_block bb, edge src_e, edge tgt_e) ...@@ -423,10 +478,13 @@ copy_phi_args (basic_block bb, edge src_e, edge tgt_e)
edges. The copy is NEW_BB. Every PHI node in every direct successor of edges. The copy is NEW_BB. Every PHI node in every direct successor of
ORIG_BB has a new argument associated with edge from NEW_BB to the ORIG_BB has a new argument associated with edge from NEW_BB to the
successor. Initialize the PHI argument so that it is equal to the PHI successor. Initialize the PHI argument so that it is equal to the PHI
argument associated with the edge from ORIG_BB to the successor. */ argument associated with the edge from ORIG_BB to the successor.
PATH and IDX are used to check if the new PHI argument has constant
value in a flow sensitive manner. */
static void static void
update_destination_phis (basic_block orig_bb, basic_block new_bb) update_destination_phis (basic_block orig_bb, basic_block new_bb,
vec<jump_thread_edge *> *path, int idx)
{ {
edge_iterator ei; edge_iterator ei;
edge e; edge e;
...@@ -434,7 +492,7 @@ update_destination_phis (basic_block orig_bb, basic_block new_bb) ...@@ -434,7 +492,7 @@ update_destination_phis (basic_block orig_bb, basic_block new_bb)
FOR_EACH_EDGE (e, ei, orig_bb->succs) FOR_EACH_EDGE (e, ei, orig_bb->succs)
{ {
edge e2 = find_edge (new_bb, e->dest); edge e2 = find_edge (new_bb, e->dest);
copy_phi_args (e->dest, e, e2); copy_phi_args (e->dest, e, e2, path, idx);
} }
} }
...@@ -443,11 +501,13 @@ update_destination_phis (basic_block orig_bb, basic_block new_bb) ...@@ -443,11 +501,13 @@ update_destination_phis (basic_block orig_bb, basic_block new_bb)
destination. destination.
Add an additional argument to any PHI nodes at the single Add an additional argument to any PHI nodes at the single
destination. */ destination. IDX is the start node in jump threading path
we start to check to see if the new PHI argument has constant
value along the jump threading path. */
static void static void
create_edge_and_update_destination_phis (struct redirection_data *rd, create_edge_and_update_destination_phis (struct redirection_data *rd,
basic_block bb) basic_block bb, int idx)
{ {
edge e = make_edge (bb, rd->path->last ()->e->dest, EDGE_FALLTHRU); edge e = make_edge (bb, rd->path->last ()->e->dest, EDGE_FALLTHRU);
...@@ -476,7 +536,7 @@ create_edge_and_update_destination_phis (struct redirection_data *rd, ...@@ -476,7 +536,7 @@ create_edge_and_update_destination_phis (struct redirection_data *rd,
from the duplicate block, then we will need to add a new argument from the duplicate block, then we will need to add a new argument
to them. The argument should have the same value as the argument to them. The argument should have the same value as the argument
associated with the outgoing edge stored in RD. */ associated with the outgoing edge stored in RD. */
copy_phi_args (e->dest, rd->path->last ()->e, e); copy_phi_args (e->dest, rd->path->last ()->e, e, rd->path, idx);
} }
/* Look through PATH beginning at START and return TRUE if there are /* Look through PATH beginning at START and return TRUE if there are
...@@ -501,6 +561,7 @@ void ...@@ -501,6 +561,7 @@ void
ssa_fix_duplicate_block_edges (struct redirection_data *rd, ssa_fix_duplicate_block_edges (struct redirection_data *rd,
ssa_local_info_t *local_info) ssa_local_info_t *local_info)
{ {
bool multi_incomings = (rd->incoming_edges->next != NULL);
edge e = rd->incoming_edges->e; edge e = rd->incoming_edges->e;
vec<jump_thread_edge *> *path = THREAD_PATH (e); vec<jump_thread_edge *> *path = THREAD_PATH (e);
...@@ -516,8 +577,10 @@ ssa_fix_duplicate_block_edges (struct redirection_data *rd, ...@@ -516,8 +577,10 @@ ssa_fix_duplicate_block_edges (struct redirection_data *rd,
edge e2; edge e2;
/* This updates the PHIs at the destination of the duplicate /* This updates the PHIs at the destination of the duplicate
block. */ block. Pass 0 instead of i if we are threading a path which
update_destination_phis (local_info->bb, rd->dup_blocks[count]); has multiple incoming edges. */
update_destination_phis (local_info->bb, rd->dup_blocks[count],
path, multi_incomings ? 0 : i);
/* Find the edge from the duplicate block to the block we're /* Find the edge from the duplicate block to the block we're
threading through. That's the edge we want to redirect. */ threading through. That's the edge we want to redirect. */
...@@ -535,7 +598,8 @@ ssa_fix_duplicate_block_edges (struct redirection_data *rd, ...@@ -535,7 +598,8 @@ ssa_fix_duplicate_block_edges (struct redirection_data *rd,
case), then the PHIs in the target already have the correct case), then the PHIs in the target already have the correct
arguments. */ arguments. */
if (e2 == victim) if (e2 == victim)
copy_phi_args (e2->dest, path->last ()->e, e2); copy_phi_args (e2->dest, path->last ()->e, e2,
path, multi_incomings ? 0 : i);
} }
else else
{ {
...@@ -567,7 +631,8 @@ ssa_fix_duplicate_block_edges (struct redirection_data *rd, ...@@ -567,7 +631,8 @@ ssa_fix_duplicate_block_edges (struct redirection_data *rd,
else if ((*path)[i]->type == EDGE_COPY_SRC_BLOCK) else if ((*path)[i]->type == EDGE_COPY_SRC_BLOCK)
{ {
remove_ctrl_stmt_and_useless_edges (rd->dup_blocks[count], NULL); remove_ctrl_stmt_and_useless_edges (rd->dup_blocks[count], NULL);
create_edge_and_update_destination_phis (rd, rd->dup_blocks[count]); create_edge_and_update_destination_phis (rd, rd->dup_blocks[count],
multi_incomings ? 0 : i);
if (count == 1) if (count == 1)
single_succ_edge (rd->dup_blocks[1])->aux = NULL; single_succ_edge (rd->dup_blocks[1])->aux = NULL;
count++; count++;
...@@ -989,7 +1054,7 @@ thread_single_edge (edge e) ...@@ -989,7 +1054,7 @@ thread_single_edge (edge e)
create_block_for_threading (bb, &rd, 0); create_block_for_threading (bb, &rd, 0);
remove_ctrl_stmt_and_useless_edges (rd.dup_blocks[0], NULL); remove_ctrl_stmt_and_useless_edges (rd.dup_blocks[0], NULL);
create_edge_and_update_destination_phis (&rd, rd.dup_blocks[0]); create_edge_and_update_destination_phis (&rd, rd.dup_blocks[0], 0);
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " Threaded jump %d --> %d to %d\n", fprintf (dump_file, " Threaded jump %d --> %d to %d\n",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment