summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Bosscher <steven@gcc.gnu.org>2005-03-10 23:28:01 +0000
committerSteven Bosscher <steven@gcc.gnu.org>2005-03-10 23:28:01 +0000
commit927630a5658fcd6707593f6b486c9aa80fcacd44 (patch)
treef843660de8e938b83421485c8cf571dcacbc0ae5
parentcebfb966e6b7eb32bc2b25f53d43847f20270577 (diff)
downloadgcc-927630a5658fcd6707593f6b486c9aa80fcacd44.tar.gz
expr.c (expand_expr_real_1): If possible, use a conditional move for expanding MIN_EXPR and MAX_EXPR.
* expr.c (expand_expr_real_1): If possible, use a conditional move for expanding MIN_EXPR and MAX_EXPR. Use temp for moving around rtx-en. From-SVN: r96269
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/expr.c55
2 files changed, 55 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0cd964faa7d..9de54901da4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2005-03-10 Steven Bosscher <stevenb@suse.de>
+
+ * expr.c (expand_expr_real_1): If possible, use a conditional
+ move for expanding MIN_EXPR and MAX_EXPR.
+ Use temp for moving around rtx-en.
+
2005-03-10 Andrew Pinski <pinskia@physics.uc.edu>
PR rtl-opt/20412
@@ -18,7 +24,7 @@
2005-03-10 Aldy Hernandez <aldyh@redhat.com>
- * doc/invoke.texi: Add 8540 to list of cpus in rs6000 cpu section.
+ * doc/invoke.texi: Add 8540 to list of cpus in rs6000 cpu section.
2005-03-10 Kazu Hirata <kazu@cs.umass.edu>
diff --git a/gcc/expr.c b/gcc/expr.c
index 07efe7089eb..775a83a3cfc 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -7876,9 +7876,9 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
/* If op1 was placed in target, swap op0 and op1. */
if (target != op0 && target == op1)
{
- rtx tem = op0;
+ temp = op0;
op0 = op1;
- op1 = tem;
+ op1 = temp;
}
/* We generate better code and avoid problems with op1 mentioning
@@ -7886,10 +7886,51 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
if (! CONSTANT_P (op1))
op1 = force_reg (mode, op1);
+#ifdef HAVE_conditional_move
+ /* Use a conditional move if possible. */
+ if (can_conditionally_move_p (mode))
+ {
+ enum rtx_code comparison_code;
+ rtx insn;
+
+ if (code == MAX_EXPR)
+ comparison_code = unsignedp ? GEU : GE;
+ else
+ comparison_code = unsignedp ? LEU : LE;
+
+ /* ??? Same problem as in expmed.c: emit_conditional_move
+ forces a stack adjustment via compare_from_rtx, and we
+ lose the stack adjustment if the sequence we are about
+ to create is discarded. */
+ do_pending_stack_adjust ();
+
+ start_sequence ();
+
+ /* Try to emit the conditional move. */
+ insn = emit_conditional_move (target, comparison_code,
+ op0, op1, mode,
+ op0, op1, mode,
+ unsignedp);
+
+ /* If we could do the conditional move, emit the sequence,
+ and return. */
+ if (insn)
+ {
+ rtx seq = get_insns ();
+ end_sequence ();
+ emit_insn (seq);
+ return target;
+ }
+
+ /* Otherwise discard the sequence and fall back to code with
+ branches. */
+ end_sequence ();
+ }
+#endif
if (target != op0)
emit_move_insn (target, op0);
- op0 = gen_label_rtx ();
+ temp = gen_label_rtx ();
/* If this mode is an integer too wide to compare properly,
compare word by word. Rely on cse to optimize constant cases. */
@@ -7898,18 +7939,18 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
{
if (code == MAX_EXPR)
do_jump_by_parts_greater_rtx (mode, unsignedp, target, op1,
- NULL_RTX, op0);
+ NULL_RTX, temp);
else
do_jump_by_parts_greater_rtx (mode, unsignedp, op1, target,
- NULL_RTX, op0);
+ NULL_RTX, temp);
}
else
{
do_compare_rtx_and_jump (target, op1, code == MAX_EXPR ? GE : LE,
- unsignedp, mode, NULL_RTX, NULL_RTX, op0);
+ unsignedp, mode, NULL_RTX, NULL_RTX, temp);
}
emit_move_insn (target, op1);
- emit_label (op0);
+ emit_label (temp);
return target;
case BIT_NOT_EXPR: