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]

[patch] Fix PR39976, sixtrack degradation


Hi,

inserting on back edges causes problems downstream by deficiencies in the 
later passes that can't deal with multiple BBs.  So let's make life not as 
tough for them by trying to avoid that situation.  We already detect some 
sitations in which surely a conflict (hence no coalescing and a copy) 
occurs, so we can as well detect some more situations.

This fixes the particular problem in sixtrack where it now generates a 
single BB loop.  I haven't verified that this also restores the 
performance fully, I would be grateful for somebody try this on powerpc 
(Luis?).

Regstrapped without regressions on x86_64-linux.  Okay?


Ciao,
Michael.
-- 
	PR middle-end/39976
	* tree-outof-ssa.c (trivially_conflicts_p): New function.
	(insert_backedge_copies): Use it.

Index: tree-outof-ssa.c
===================================================================
--- tree-outof-ssa.c	(Revision 147214)
+++ tree-outof-ssa.c	(Arbeitskopie)
@@ -853,6 +853,47 @@ remove_ssa_form (bool perform_ter, struc
 }
 
 
+/* Return true if we can determine that the SSA_NAMEs RESULT (a result
+   of a PHI node) and ARG (one of its arguments) conflict.  Return false
+   otherwise, also when we simply aren't sure.  */
+
+static bool
+trivially_conflicts_p (basic_block bb, tree result, tree arg)
+{
+  use_operand_p use;
+  imm_use_iterator imm_iter;
+  gimple defa = SSA_NAME_DEF_STMT (arg);
+
+  /* If ARG isn't defined in the same block it's too complicated for
+     our little mind.  */
+  if (gimple_bb (defa) != bb)
+    return false;
+
+  FOR_EACH_IMM_USE_FAST (use, imm_iter, result)
+    {
+      gimple_stmt_iterator gsi;
+      gimple use_stmt = USE_STMT (use);
+      /* Now, if there's a use of RESULT that lies outside this basic block,
+	 then there surely is a conflict with ARG.  */
+      if (gimple_bb (use_stmt) != bb)
+	return true;
+      if (gimple_code (use_stmt) == GIMPLE_PHI)
+	continue;
+      /* The use now is in a real stmt of BB, so if ARG was defined
+         in a PHI node (like RESULT) both conflict.  */
+      if (gimple_code (defa) == GIMPLE_PHI)
+	return true;
+      /* If the use of RESULT occurs after the definition of ARG,
+         the two conflict too.  */
+      for (gsi = gsi_start_bb (bb); gsi_stmt (gsi) != use_stmt; gsi_next (&gsi))
+	if (gsi_stmt (gsi) == defa)
+	  return true;
+    }
+  
+  return false;
+}
+
+
 /* Search every PHI node for arguments associated with backedges which
    we can trivially determine will need a copy (the argument is either
    not an SSA_NAME or the argument has a different underlying variable
@@ -892,7 +933,8 @@ insert_backedge_copies (void)
 		 needed.  */
 	      if ((e->flags & EDGE_DFS_BACK)
 		  && (TREE_CODE (arg) != SSA_NAME
-		      || SSA_NAME_VAR (arg) != result_var))
+		      || SSA_NAME_VAR (arg) != result_var
+		      || trivially_conflicts_p (bb, result, arg)))
 		{
 		  tree name;
 		  gimple stmt, last = NULL;


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