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]

[4.1/4.0/3.4] fix pr19672 by tuning expansion of TRUTH_{AND,OR}_EXPR


This patch fixes pr19672 (pessimized code for a loop whose condition has && or ||) by adding a special-cased expansion of TRUTH_AND_EXPR and TRUTH_OR_EXPR in do_jump.

Like COND_EXPR or NE_EXPR, it makes sense to have a special expansion so that

if (a || b) goto xy;

can be translated to

  if (a) goto xy;
  if (b) goto xy;

Likewise, in the PR's testcase

if (!(a && b)) goto out_of_loop;

will become

 if (!a) goto out_of_loop;
 if (!b) goto out_of_loop;

All this is done only if the branch cost is not too high.

Bootstrapped/regtested i686-pc-linux-gnu, fixes the testcase (there is still a consistent 1% slowdown with respect to 3.2, which seems to be due to different basic block reordering choices, but way better than the 50% pessimization we used to show). Ok for 4.1/4.0/3.4?

Paolo


2005-10-18  Paolo Bonzini  <bonzini@gnu.org>

	* dojump.c (do_jump): Handle TRUTH_AND_EXPR and TRUTH_OR_EXPR here.

Index: dojump.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/dojump.c,v
retrieving revision 1.42
diff -u -r1.42 dojump.c
--- dojump.c	6 Jul 2005 21:07:45 -0000	1.42
+++ dojump.c	18 Oct 2005 17:06:53 -0000
@@ -510,6 +510,42 @@
       }
       break;
 
+    case TRUTH_AND_EXPR:
+      /* High branch cost, expand as the bitwise AND of the conditions.  */
+      if (BRANCH_COST >= 4)
+	goto normal;
+
+      if (if_false_label == NULL_RTX)
+        {
+	  drop_through_label = gen_label_rtx ();
+          do_jump (TREE_OPERAND (exp, 0), drop_through_label, NULL_RTX);
+          do_jump (TREE_OPERAND (exp, 1), NULL_RTX, if_true_label);
+	}
+      else
+	{
+	  do_jump (TREE_OPERAND (exp, 0), if_false_label, NULL_RTX);
+          do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
+	}
+      break;
+
+    case TRUTH_OR_EXPR:
+      /* High branch cost, expand as the bitwise OR of the conditions.  */
+      if (BRANCH_COST >= 4)
+	goto normal;
+
+      if (if_true_label == NULL_RTX)
+	{
+          drop_through_label = gen_label_rtx ();
+          do_jump (TREE_OPERAND (exp, 0), NULL_RTX, drop_through_label);
+          do_jump (TREE_OPERAND (exp, 1), if_false_label, NULL_RTX);
+	}
+      else
+	{
+          do_jump (TREE_OPERAND (exp, 0), NULL_RTX, if_true_label);
+          do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label);
+	}
+      break;
+
       /* Special case:
           __builtin_expect (<test>, 0)	and
           __builtin_expect (<test>, 1)
@@ -540,8 +576,8 @@
 	      }
 	  }
       }
+ 
       /* Fall through and generate the normal code.  */
-
     default:
     normal:
       temp = expand_expr (exp, NULL_RTX, VOIDmode, 0);

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