This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Fix PR39976, sixtrack degradation
- From: Michael Matz <matz at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Luis Machado <luisgpm at linux dot vnet dot ibm dot com>
- Date: Wed, 13 May 2009 20:15:10 +0200 (CEST)
- Subject: [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;