diff options
author | Bin Cheng <bin.cheng@arm.com> | 2014-05-05 07:36:30 +0000 |
---|---|---|
committer | Bin Cheng <amker@gcc.gnu.org> | 2014-05-05 07:36:30 +0000 |
commit | cb8f1a57612438e0922264c142cfa9c71aa67771 (patch) | |
tree | 347e103d5129b8022d8c329578471dace850d580 /gcc | |
parent | f93bc5b31a74f46a6c190a2bee3bc136ee3e2440 (diff) | |
download | gcc-cb8f1a57612438e0922264c142cfa9c71aa67771.zip gcc-cb8f1a57612438e0922264c142cfa9c71aa67771.tar.gz gcc-cb8f1a57612438e0922264c142cfa9c71aa67771.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c | 2 | ||||
-rw-r--r-- | gcc/tree-ssa-threadupdate.c | 93 |
4 files changed, 95 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9f374f1..cd6aa9d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +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> * config/rs6000/rs6000.h (RS6000_BTM_HARD_FLOAT): New define. diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4813489..8cbc790 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +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> * gcc.target/powerpc/pack02.c (dg-options): Add -mhard-float. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c index e85a244..cafdf13 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c @@ -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, skipping the known-true "b_elt && kill_elt" in the second 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" } } */ diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c index f458d6a..0a24a5c 100644 --- a/gcc/tree-ssa-threadupdate.c +++ b/gcc/tree-ssa-threadupdate.c @@ -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 -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; int src_indx = src_e->dest_idx; @@ -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)) { gimple phi = gsi_stmt (gsi); + tree def = gimple_phi_arg_def (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) 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 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 -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 e; @@ -434,7 +492,7 @@ update_destination_phis (basic_block orig_bb, basic_block new_bb) FOR_EACH_EDGE (e, ei, orig_bb->succs) { 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) destination. 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 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); @@ -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 to them. The argument should have the same value as the argument 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 @@ -501,6 +561,7 @@ void ssa_fix_duplicate_block_edges (struct redirection_data *rd, ssa_local_info_t *local_info) { + bool multi_incomings = (rd->incoming_edges->next != NULL); edge e = rd->incoming_edges->e; vec<jump_thread_edge *> *path = THREAD_PATH (e); @@ -516,8 +577,10 @@ ssa_fix_duplicate_block_edges (struct redirection_data *rd, edge e2; /* This updates the PHIs at the destination of the duplicate - block. */ - update_destination_phis (local_info->bb, rd->dup_blocks[count]); + block. Pass 0 instead of i if we are threading a path which + 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 threading through. That's the edge we want to redirect. */ @@ -535,7 +598,8 @@ ssa_fix_duplicate_block_edges (struct redirection_data *rd, case), then the PHIs in the target already have the correct arguments. */ 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 { @@ -567,7 +631,8 @@ ssa_fix_duplicate_block_edges (struct redirection_data *rd, else if ((*path)[i]->type == EDGE_COPY_SRC_BLOCK) { 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) single_succ_edge (rd->dup_blocks[1])->aux = NULL; count++; @@ -989,7 +1054,7 @@ thread_single_edge (edge e) create_block_for_threading (bb, &rd, 0); 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)) fprintf (dump_file, " Threaded jump %d --> %d to %d\n", |