This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[4.1/4.0/3.4] fix pr19672 by tuning expansion of TRUTH_{AND,OR}_EXPR
- From: Paolo Bonzini <paolo dot bonzini at lu dot unisi dot ch>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 18 Oct 2005 19:14:15 +0200
- Subject: [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);