This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Try to avoid mark_virtual_operands_for_renmaing in call-cdce


It's fairly easy to update the virtual ops when the call has no EH edges,
which should be cheaper than mark_virtual_operands_for_renaming.

Tested on x86_64-linux-gnu, arm-linux-gnueabi and aarch64-linux-gnu.
OK to install?

Thanks,
Richard


gcc/
	* tree-call-cdce.c (join_vdefs): New function.
	(shrink_wrap_one_built_in_call): Use it when the call does not
	need to end a block.  Call mark_virtual_operands_for_renaming
	otherwise.
	(pass_call_cdce::execute): Don't call
	mark_virtual_operands_for_renaming here.

diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c
index 72828dd..dcaa974 100644
--- a/gcc/tree-call-cdce.c
+++ b/gcc/tree-call-cdce.c
@@ -708,6 +708,23 @@ gen_shrink_wrap_conditions (gcall *bi_call, vec<gimple *> conds,
 /* Probability of the branch (to the call) is taken.  */
 #define ERR_PROB 0.01
 
+/* Replace BI_CALL's vdef with a phi that uses BI_CALL's definition
+   when WITH_CALL is taken and the previous definition when WITHOUT_CALL
+   is taken.  JOIN_BB is the target of both edges.  */
+
+static void
+join_vdefs (gcall *bi_call, edge with_call, edge without_call,
+	    basic_block join_bb)
+{
+  tree old_vuse = gimple_vuse (bi_call);
+  tree old_vdef = gimple_vdef (bi_call);
+  tree new_vdef = copy_ssa_name (old_vuse);
+  gphi *phi = create_phi_node (new_vdef, join_bb);
+  replace_uses_by (old_vdef, new_vdef);
+  add_phi_arg (phi, old_vuse, without_call, UNKNOWN_LOCATION);
+  add_phi_arg (phi, old_vdef, with_call, UNKNOWN_LOCATION);
+}
+
 /* The function to shrink wrap a partially dead builtin call
    whose return value is not used anywhere, but has to be kept
    live due to potential error condition.  Returns true if the
@@ -764,7 +781,8 @@ shrink_wrap_one_built_in_call (gcall *bi_call)
   bi_call_bb = gimple_bb (bi_call);
 
   /* Now find the join target bb -- split bi_call_bb if needed.  */
-  if (stmt_ends_bb_p (bi_call))
+  bool call_must_end_bb_p = stmt_ends_bb_p (bi_call);
+  if (call_must_end_bb_p)
     {
       /* If the call must be the last in the bb, don't split the block,
 	 it could e.g. have EH edges.  */
@@ -822,6 +840,12 @@ shrink_wrap_one_built_in_call (gcall *bi_call)
   join_tgt_in_edge_fall_thru->count =
       guard_bb->count - bi_call_in_edge0->count;
 
+  if (call_must_end_bb_p)
+    mark_virtual_operands_for_renaming (cfun);
+  else
+    join_vdefs (bi_call, join_tgt_in_edge_from_call,
+		join_tgt_in_edge_fall_thru, join_tgt_bb);
+
   /* Code generation for the rest of the conditions  */
   basic_block prev_guard_bb = NULL;
   while (nconds > 0)
@@ -978,9 +1002,6 @@ pass_call_cdce::execute (function *fun)
   if (something_changed)
     {
       free_dominance_info (CDI_POST_DOMINATORS);
-      /* As we introduced new control-flow we need to insert PHI-nodes
-         for the call-clobbers of the remaining call.  */
-      mark_virtual_operands_for_renaming (fun);
       return TODO_update_ssa;
     }
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]