This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[cond-optab] Yesterday's patch revised - use prepare_operand in emit_store_flag too
- From: Paolo Bonzini <bonzini at gnu dot org>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 24 Mar 2009 11:40:24 +0100
- Subject: [cond-optab] Yesterday's patch revised - use prepare_operand in emit_store_flag too
prepare_operand is useful but not available in expmed.c. This version
of yesterday's patch makes the cstore and cbranch code more similar by
declaring it non-static.
Paolo
2009-03-23 Paolo Bonzini <bonzini@gnu.org>
* optabs.c (emit_cmp_and_jump_insn_1): Rebuild operands[0]
of the cbranch pattern after preparing the operands.
(prepare_operand): Make non-static.
* expmed.c (emit_store_flag): Use prepare_operand.
* expr.h (prepare_operand): Declare it.
Index: gcc/optabs.c
===================================================================
--- gcc/optabs.c (branch cond-optab)
+++ gcc/optabs.c (working copy)
@@ -4175,7 +4175,7 @@ prepare_cmp_insn (rtx *px, rtx *py, enum
WIDER_MODE (UNSIGNEDP determines whether it is an unsigned conversion), and
that it is accepted by the operand predicate. Return the new value. */
-static rtx
+rtx
prepare_operand (int icode, rtx x, int opnum, enum machine_mode mode,
enum machine_mode wider_mode, int unsignedp)
{
@@ -4219,6 +4219,11 @@ emit_cmp_and_jump_insn_1 (rtx x, rtx y,
{
x = prepare_operand (icode, x, 1, mode, wider_mode, unsignedp);
y = prepare_operand (icode, y, 2, mode, wider_mode, unsignedp);
+
+ /* Rebuild test so as to give freedom to the machine description
+ whether to use operands[1]/operands[2] or not. */
+ test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
+ gcc_assert (insn_data[icode].operand[0].predicate (test, VOIDmode));
emit_jump_insn (GEN_FCN (icode) (test, x, y, label));
return;
}
Index: gcc/expmed.c
===================================================================
--- gcc/expmed.c (branch cond-optab)
+++ gcc/expmed.c (working copy)
@@ -5147,7 +5147,7 @@ emit_store_flag (rtx target, enum rtx_co
enum machine_mode target_mode = GET_MODE (target);
enum mode_class mclass;
rtx tem;
- rtx last = get_last_insn ();
+ rtx last;
rtx pattern, comparison;
if (unsignedp)
@@ -5289,40 +5289,24 @@ emit_store_flag (rtx target, enum rtx_co
icode = optab_handler (cstore_optab, optab_mode)->insn_code;
if (icode != CODE_FOR_nothing)
{
+ rtx x, y;
enum machine_mode result_mode
= insn_data[(int) icode].operand[0].mode;
- rtx cstore_op0 = op0;
- rtx cstore_op1 = op1;
do_pending_stack_adjust ();
last = get_last_insn ();
- if (compare_mode != mode)
- {
- cstore_op0 = convert_modes (compare_mode, mode, cstore_op0,
- unsignedp);
- cstore_op1 = convert_modes (compare_mode, mode, cstore_op1,
- unsignedp);
- }
-
- if (!insn_data[(int) icode].operand[2].predicate (cstore_op0,
- compare_mode))
- cstore_op0 = copy_to_mode_reg (compare_mode, cstore_op0);
-
- if (!insn_data[(int) icode].operand[3].predicate (cstore_op1,
- compare_mode))
- cstore_op1 = copy_to_mode_reg (compare_mode, cstore_op1);
+ x = prepare_operand (icode, op0, 2, mode, compare_mode, unsignedp);
+ y = prepare_operand (icode, op1, 3, mode, compare_mode, unsignedp);
+ comparison = gen_rtx_fmt_ee (code, result_mode, x, y);
+ gcc_assert (insn_data[icode].operand[1].predicate (comparison, VOIDmode));
- comparison = gen_rtx_fmt_ee (code, result_mode, cstore_op0,
- cstore_op1);
subtarget = target;
-
if (optimize || !(insn_data[(int) icode].operand[0].predicate
(subtarget, result_mode)))
subtarget = gen_reg_rtx (result_mode);
- pattern = GEN_FCN (icode) (subtarget, comparison, cstore_op0,
- cstore_op1);
+ pattern = GEN_FCN (icode) (subtarget, comparison, x, y);
if (pattern)
{
@@ -5330,10 +5314,12 @@ emit_store_flag (rtx target, enum rtx_co
return emit_store_flag_1 (target, subtarget, result_mode,
normalizep);
}
+
+ delete_insns_since (last);
}
}
- delete_insns_since (last);
+ last = get_last_insn ();
/* If optimizing, use different pseudo registers for each insn, instead
of reusing the same pseudo. This leads to better CSE, but slows
Index: gcc/expr.h
===================================================================
--- gcc/expr.h (branch cond-optab)
+++ gcc/expr.h (working copy)
@@ -298,6 +298,9 @@ extern rtx expand_simple_unop (enum mach
perform the operation described by CODE and MODE. */
extern int have_insn_for (enum rtx_code, enum machine_mode);
+extern rtx prepare_operand (int, rtx, int, enum machine_mode, enum machine_mode,
+ int);
+
/* Emit code to make a call to a constant function or a library call. */
extern void emit_libcall_block (rtx, rtx, rtx, rtx);