From: Richard Biener Date: Thu, 18 Aug 2016 07:21:11 +0000 (+0000) Subject: ssa-iterators.h (ssa_vuse_operand): New inline. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=eeead3a6f1c090dceb9c2b8f6a92855369702244;p=gcc.git ssa-iterators.h (ssa_vuse_operand): New inline. 2016-08-18 Richard Biener * ssa-iterators.h (ssa_vuse_operand): New inline. * tree-if-conv.c (ifc_temp_var): Update virtual operand. (predicate_all_scalar_phis): Use remove_phi_node to remove phi nodes predicated. Delay removing virtual PHIs. (predicate_mem_writes): Update virtual operands. (combine_blocks): Likewise. Propagate out remaining virtual PHIs. (tree_if_conversion): Do not rewrite virtual SSA form. * tree-phinodes.c (release_phi_node): Make static. * tree-phinodes.h (release_phi_node): Remove. From-SVN: r239560 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5ec8a2cc33a..17dab645a95 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2016-08-18 Richard Biener + + * ssa-iterators.h (ssa_vuse_operand): New inline. + * tree-if-conv.c (ifc_temp_var): Update virtual operand. + (predicate_all_scalar_phis): Use remove_phi_node to remove + phi nodes predicated. Delay removing virtual PHIs. + (predicate_mem_writes): Update virtual operands. + (combine_blocks): Likewise. Propagate out remaining virtual PHIs. + (tree_if_conversion): Do not rewrite virtual SSA form. + * tree-phinodes.c (release_phi_node): Make static. + * tree-phinodes.h (release_phi_node): Remove. + 2016-08-18 Jakub Jelinek * config/i386/i386.c (enum ix86_builtins): Remove IX86_BUILTIN_* diff --git a/gcc/ssa-iterators.h b/gcc/ssa-iterators.h index b6d8f3c67de..7e656e164a0 100644 --- a/gcc/ssa-iterators.h +++ b/gcc/ssa-iterators.h @@ -699,6 +699,15 @@ single_ssa_use_operand (gimple *stmt, int flags) return NULL_USE_OPERAND_P; } +/* Return the single virtual use operand in STMT if present. Otherwise + return NULL. */ +static inline use_operand_p +ssa_vuse_operand (gimple *stmt) +{ + if (! gimple_vuse (stmt)) + return NULL_USE_OPERAND_P; + return USE_OP_PTR (gimple_use_ops (stmt)); +} /* If there is a single operand in STMT matching FLAGS, return it. Otherwise diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 4253d194ed4..a57c1c5a25f 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -326,6 +326,7 @@ ifc_temp_var (tree type, tree expr, gimple_stmt_iterator *gsi) { tree new_name = make_temp_ssa_name (type, NULL, "_ifc_"); gimple *stmt = gimple_build_assign (new_name, expr); + gimple_set_vuse (stmt, gimple_vuse (gsi_stmt (*gsi))); gsi_insert_before (gsi, stmt, GSI_SAME_STMT); return new_name; } @@ -1946,12 +1947,14 @@ predicate_all_scalar_phis (struct loop *loop) while (!gsi_end_p (phi_gsi)) { phi = phi_gsi.phi (); - predicate_scalar_phi (phi, &gsi); - release_phi_node (phi); - gsi_next (&phi_gsi); + if (virtual_operand_p (gimple_phi_result (phi))) + gsi_next (&phi_gsi); + else + { + predicate_scalar_phi (phi, &gsi); + remove_phi_node (&phi_gsi, false); + } } - - set_phi_nodes (bb, NULL); } } @@ -2218,11 +2221,18 @@ predicate_mem_writes (loop_p loop) = gimple_build_call_internal (IFN_MASK_LOAD, 3, addr, ptr, mask); gimple_call_set_lhs (new_stmt, lhs); + gimple_set_vuse (new_stmt, gimple_vuse (stmt)); } else - new_stmt - = gimple_build_call_internal (IFN_MASK_STORE, 4, addr, ptr, - mask, rhs); + { + new_stmt + = gimple_build_call_internal (IFN_MASK_STORE, 4, addr, ptr, + mask, rhs); + gimple_set_vuse (new_stmt, gimple_vuse (stmt)); + gimple_set_vdef (new_stmt, gimple_vdef (stmt)); + SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt; + } + gsi_replace (&gsi, new_stmt, true); } else if (gimple_vdef (stmt)) @@ -2361,6 +2371,20 @@ combine_blocks (struct loop *loop) } merge_target_bb = loop->header; + + /* Get at the virtual def valid for uses starting at the first block + we merge into the header. Without a virtual PHI the loop has the + same virtual use on all stmts. */ + gphi *vphi = get_virtual_phi (loop->header); + tree last_vdef = NULL_TREE; + if (vphi) + { + last_vdef = gimple_phi_result (vphi); + for (gimple_stmt_iterator gsi = gsi_start_bb (loop->header); + ! gsi_end_p (gsi); gsi_next (&gsi)) + if (gimple_vdef (gsi_stmt (gsi))) + last_vdef = gimple_vdef (gsi_stmt (gsi)); + } for (i = 1; i < orig_loop_num_nodes; i++) { gimple_stmt_iterator gsi; @@ -2371,6 +2395,24 @@ combine_blocks (struct loop *loop) if (bb == exit_bb || bb == loop->latch) continue; + /* We release virtual PHIs late because we have to propagate them + out using the current VUSE. The def might be the one used + after the loop. */ + vphi = get_virtual_phi (bb); + if (vphi) + { + imm_use_iterator iter; + use_operand_p use_p; + gimple *use_stmt; + FOR_EACH_IMM_USE_STMT (use_stmt, iter, gimple_phi_result (vphi)) + { + FOR_EACH_IMM_USE_ON_STMT (use_p, iter) + SET_USE (use_p, last_vdef); + } + gsi = gsi_for_stmt (vphi); + remove_phi_node (&gsi, true); + } + /* Make stmts member of loop->header and clear range info from all stmts in BB which is now no longer executed conditional on a predicate we could have derived it from. */ @@ -2378,6 +2420,16 @@ combine_blocks (struct loop *loop) { gimple *stmt = gsi_stmt (gsi); gimple_set_bb (stmt, merge_target_bb); + /* Update virtual operands. */ + if (last_vdef) + { + use_operand_p use_p = ssa_vuse_operand (stmt); + if (use_p + && USE_FROM_PTR (use_p) != last_vdef) + SET_USE (use_p, last_vdef); + if (gimple_vdef (stmt)) + last_vdef = gimple_vdef (stmt); + } if (predicated[i]) { ssa_op_iter i; @@ -2389,7 +2441,7 @@ combine_blocks (struct loop *loop) /* Update stmt list. */ last = gsi_last_bb (merge_target_bb); - gsi_insert_seq_after (&last, bb_seq (bb), GSI_NEW_STMT); + gsi_insert_seq_after_without_update (&last, bb_seq (bb), GSI_NEW_STMT); set_bb_seq (bb, NULL); delete_basic_block (bb); @@ -2399,9 +2451,29 @@ combine_blocks (struct loop *loop) This reduces the number of basic blocks to two, to please the vectorizer that handles only loops with two nodes. */ if (exit_bb - && exit_bb != loop->header - && can_merge_blocks_p (loop->header, exit_bb)) - merge_blocks (loop->header, exit_bb); + && exit_bb != loop->header) + { + /* We release virtual PHIs late because we have to propagate them + out using the current VUSE. The def might be the one used + after the loop. */ + vphi = get_virtual_phi (exit_bb); + if (vphi) + { + imm_use_iterator iter; + use_operand_p use_p; + gimple *use_stmt; + FOR_EACH_IMM_USE_STMT (use_stmt, iter, gimple_phi_result (vphi)) + { + FOR_EACH_IMM_USE_ON_STMT (use_p, iter) + SET_USE (use_p, last_vdef); + } + gimple_stmt_iterator gsi = gsi_for_stmt (vphi); + remove_phi_node (&gsi, true); + } + + if (can_merge_blocks_p (loop->header, exit_bb)) + merge_blocks (loop->header, exit_bb); + } free (ifc_bbs); ifc_bbs = NULL; @@ -2669,8 +2741,6 @@ tree_if_conversion (struct loop *loop) ifcvt_local_dce (loop->header); todo |= TODO_cleanup_cfg; - mark_virtual_operands_for_renaming (cfun); - todo |= TODO_update_ssa_only_virtuals; cleanup: if (ifc_bbs) diff --git a/gcc/tree-phinodes.c b/gcc/tree-phinodes.c index 1bbf3949789..6977770c979 100644 --- a/gcc/tree-phinodes.c +++ b/gcc/tree-phinodes.c @@ -207,7 +207,7 @@ make_phi_node (tree var, int len) /* We no longer need PHI, release it so that it may be reused. */ -void +static void release_phi_node (gimple *phi) { size_t bucket; diff --git a/gcc/tree-phinodes.h b/gcc/tree-phinodes.h index a924d3cb8b2..6cc76fa7072 100644 --- a/gcc/tree-phinodes.h +++ b/gcc/tree-phinodes.h @@ -21,7 +21,6 @@ along with GCC; see the file COPYING3. If not see #define GCC_TREE_PHINODES_H extern void phinodes_print_statistics (void); -extern void release_phi_node (gimple *); extern void reserve_phi_args_for_new_edge (basic_block); extern void add_phi_node_to_bb (gphi *phi, basic_block bb); extern gphi *create_phi_node (tree, basic_block);